I can't get the length of the list in the widget although I wrote everything correct
this is my cubit
class AppCubit extends Cubit<NewsStates> {
AppCubit() : super(NewsInit());
static AppCubit get(context) => BlocProvider.of(context);
MianTeams? mianTeams;
void getTimes() {
emit(NewsLoding());
DioHelper.getData(
Qurey: {"action": "get_teams", "league_id": "141", "APIkey": api})
.then((value) {
mianTeams = MianTeams.fromJson(value.data);
//////////////// i can get the length here in cubit
print(mianTeams!.team.length);
emit(NewsSucsess());
}).catchError((onError) {
print(onError.toString());
emit(NewsErorr(onError.toString()));
});
}
this is my model
class MianTeams {
List<TeamsModel> team = [];
MianTeams.fromJson(List<dynamic> json) {
json.forEach((e) {
team.add(TeamsModel.fromJson(e));
});
}
}
class TeamsModel {
String? teamKey;
String? teamName;
String? teamBadge;
List<Players> players = [];
TeamsModel.fromJson(Map<String, dynamic> json) {
teamKey = json['team_key'];
teamName = json['team_name'];
teamBadge = json['team_badge'];
json['players'].forEach((e) {
players.add(Players.fromJson(e));
});
}
}
but in Widget I can't get the length to set the itemCount of List View separated
this is my statelessWidget
class Teams extends StatelessWidget {
const Teams({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocConsumer<AppCubit, NewsStates>(
listener: (context, state) {},
builder: (context, state) {
// print(AppCubit.get(context).mianTeams!.team.length);
return Scaffold(
appBar: AppBar(),
body: ListView.separated(
itemBuilder: (context, index) => Divider(),
separatorBuilder: (context, index) => Divider(),
itemCount: AppCubit.get(context).mianTeams!.team.length),
);
});
}
}
I don't know what's wrong and I think I wrote everything correctly
CodePudding user response:
The problem is that mianTeams
is null until after getTimes()
is called and the response is received from your API. So when the ListView tries to build initially, it's trying to get the length of a null list.
Instead of storing mianTeams
directly as a property of the Cubit, you should make it a property of one of your State classes. Probably NewsSuccess
- then the list will always be available in that state. And if the Cubit is in a different state, you can display a loading indicator or something.
Your Cubit might then look something like this:
class AppCubit extends Cubit<NewsStates> {
AppCubit() : super(NewsInit());
static AppCubit get(context) => BlocProvider.of(context);
void getTimes() {
emit(NewsLoding());
DioHelper.getData(
Qurey: {"action": "get_teams", "league_id": "141", "APIkey": api})
.then((value) {
final mianTeams = MianTeams.fromJson(value.data);
emit(NewsSucsess(mianTeams: mianTeams));
}).catchError((onError) {
print(onError.toString());
emit(NewsErorr(onError.toString()));
});
}
}
And your widget might be something like:
class Teams extends StatelessWidget {
const Teams({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocConsumer<AppCubit, NewsStates>(
listener: (context, state) {},
builder: (context, state) {
return Scaffold(
appBar: AppBar(),
body: _buildBody(state),
});
}
Widget _buildBody(NewsStates state) {
if (state is NewsError) {
// For example
return Text("Error: ${state.message}");
} else if (state is NewsLoding) {
// For example
return const CircularProgressIndicator();
} else if (state is NewsSuccess) {
return ListView.separated(
itemBuilder: (context, index) => Divider(),
separatorBuilder: (context, index) => Divider(),
itemCount: state.mianTeams.team.length),
);
} else {
// Handle any other possible states you have
}
}
}
CodePudding user response:
You can use the state
from builder
itemCount: state.mianTeams?.team.length,