I have a scenario where a user logins in he is either redirected to dashboard or another screen. At some point data is pulled from the server and saved to the local db, and then I render it to the dashboard screen. Whenever the user logins in for the first time I get this error
Unhandled Exception: The method '[]' was called on null
I think my dashboard is set before the data is loaded, I have tried to set the setstate(){}
but I keep on getting it
this is my implemntation
@override
void initState() {
super.initState();
init();
}
Future<void> init() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String userid = prefs.getString("id") ?? "";
token = prefs.getString("auth_token");
List<ParticipantRegistrationData> list = await db.getParticipants();
for (var i in list) {
List<dynamic> sched = await db.getScheduleByparticipantId(i.participantid!);
List<int> missingOrComplete = [0, 0];
for (var j in sched) {
if (j.showUp >= 1 ) {
missingOrComplete[1] ;
} else if (j.showUp == 0 && DateTime.parse(j.windowEnd).isBefore(DateTime.now())) {
missingOrComplete[0] ;
}
}
participantCounts[i.participantid!] = missingOrComplete;
}
setState(() async {
participantSchedules = await db.getSchedulesByUserId(userid);
participants = await db.getParticipantsById(userid);
name = prefs.getString("fullname");
getTransactions();
});
// use db to draw data
}
then the get transaction function which gets the data to display in the dashboard
void getTransactions() {
for (ParticipantRegistrationData data in participants) {
setState(() {
transactionList.add(WATransactionModel(
name: data.fullname,
participantid: data.participantid,
gender: data.gender,
completedScheduleid: '15',
missedSchedule: '4',
color: Color(0xFF26C884),
colors: Color(0xFFFF1744),
title: 'Name: ',
completedSchedule: 'Schedule',
image: 'images/walletApp/man.png',
missed: 'Missed: ${participantCounts[data.participantid!][0]}',
completed: 'Completed: ${participantCounts[data.participantid!][1]}',
description: 'Number: ',
));
});
}
}
the line which keep on throwing the error is
missed: 'Missed: ${participantCounts[data.participantid!][0]}',
Which state should I set my app to load the contents first before seting the ui, Am a bit confused or how should I set the redirect(routes to refresh the page before loading the ui) Or setting the data first before the UI?
Update 1: I forgot to mention when I go to another screen and come back the data is already loaded and no error. The error occurs when am setting the screen for the first time
CodePudding user response:
the way of writing function is correct. However, when we call a function in initState, it doesn't await itself and runs parallel to your build method. So one way is to provide a check to your build method.
For example:
participantCounts==null || participantCounts.isEmpty? return CircularProgressIndicator() : return Container();
So, in this case, your build method will show loader until your data is available.
I would also suggest you to implement any State Management technique for a better handling.
CodePudding user response:
I believe this is your problem. void getTransactions() {
should be Future<void>getTransactions() async {
and the when you call the function you need to await it so you have to make the function you call response in async.
So the void getTransactions() {
should change to
Future<void>getTransactions() async {
and it will the data correctly with no error