Home > Net >  How to return a value from an async function which also awaits for a value
How to return a value from an async function which also awaits for a value

Time:07-20

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).

  • Related