I am new to Flutter and the Dart programming language. I am making a shift-assignment app, but am stuck on this - I need to return a string from an async function which also waits for a value from other async functions. This is what I have written so far:
Future<String> getNumberOfShiftsText() async {
int weekShiftCount = 0;
List<DateTime> shiftTimes = [];
await getUserDetailsFromServer().then((value){
await getAppointmentsFromServer(cid, isEmployer, rolesList).then((aValue) {
List<HiveAppointment> appointmentList = appointmentBox.values.toList();
for (int i = 0; i < appointmentList.length; i ) {
if (appointmentList[i].startTime.isBefore(DateTime.now().add(const Duration(days: 7)))) {
weekShiftCount = 1;
shiftTimes.add(appointmentList[i].startTime);
}
}
});
});
return Future.delayed(const Duration(seconds: 1), () => '$weekShiftCount shift(s) assigned to you in the next 7 days',);
}
On running this, I get the error:
A non-null value must be returned since the return type 'String' doesn't allow null. Future getNumberOfShiftsText() async {
Any ideas on how I can solve this? Any help would be much appreciated. Thanks in advance, and I apologize for my lack of knowledge.
CodePudding user response:
I am not really sure about the core issue of your problem. But your code does contain a problematic pattern with mixing then()
and await
which can make your program run in an unexpected way.
I suggest rewrite your code into something like this:
Future<String> getNumberOfShiftsText() async {
int weekShiftCount = 0;
List<DateTime> shiftTimes = [];
final value = await getUserDetailsFromServer();
final aValue = await getAppointmentsFromServer(cid, isEmployer, rolesList);
List<HiveAppointment> appointmentList = appointmentBox.values.toList();
for (int i = 0; i < appointmentList.length; i ) {
if (appointmentList[i]
.startTime
.isBefore(DateTime.now().add(const Duration(days: 7)))) {
weekShiftCount = 1;
shiftTimes.add(appointmentList[i].startTime);
}
}
return '$weekShiftCount shift(s) assigned to you in the next 7 days';
}
I am not sure about your value
variable since you are not using it in your code. Also the "wait 1 second before returning" has been removed since I think you added this because you did not know when the async code was done.
The rewritten code fixes this so when the return
statement are executed, we know the other code are done being executed.
If you still have issues, can you provide a stacktrace combined with the full error so I know where the issue might be.
CodePudding user response:
General suggestion
Avoid then
whenever you can. Always prefer await
.
Explanations
await
makes so that dart stays at that line waiting for the function answer so you can do:
Future<int> func() async {
return 0;
}
int i = await func();
then
also returns a Future
which is the value you return inside its lambda or tearOff. But its idea is so that you can process asynchronous things inside a synchronous function. Means that whenever the future process gets done, it will start working on the then
function, it will run "at the same time" (kinda) as the overlaying function (as I understand it, but you can always look for Decoding Flutter playlist on Youtube for trying to understand all this background processes better).