skip to Main Content

I’m fetching data from APIs in Flutter. The data come from a several APIs, so I’m using Future.wait to make it smoother. I’ve got this variable:

late List<Cast> castMembers;

and this function:

 Future<List<Cast>> getCast() async {
    List<Cast> members= [];
    // here is the logic of serialization etc...
    return members;
  }

and finally a function with Future.wait:

Future<void> callApi() async{
await Future.wait([       
        getAdresses(),
        getCountries(),  
        getPrices(),
        castMembers=await getCast()
      ]);
}

In this way Im getting an error. If I put the castMembers=await getCast() before the Future.wait it works fine, but in this case the methods inside the Future.wait won’t excecute while we are waitng for the getCast().

Do you have any suggestion for this?

2

Answers


  1. The should not have the field castMembers as a member in the array, because it is not a Future.

    When you type castMembers=await getCast(), this evaluates getCast(), puts its value in castMembers, and adds this value to the list.

    In other words, you should have:

    class A {
      late List<Cast> castMembers;
    
      Future<void> callApi() async {
        await Future.wait([
          getAdresses(),
          getCountries(),
          getPrices(),
          getCast(),
        ]);
      }
    
      Future<List<Cast>> getCast() async {
        List<Cast> members = [];
        return members;
      }
    
      Future<String> getAdresses() async => '';
    
      Future<int> getCountries() async => 1;
    
      Future<List<double>> getPrices() async => List.of();
    }
    
    class Cast {}
    

    instead of

    await Future.wait([       
      getAdresses(),
      getCountries(),  
      getPrices(),
      castMembers=await getCast()
    ]);
    

    If you want the initialize the variable, then do it separately:

    castMembers = await getCast();
    await Future.wait([
      getAdresses(),
      getCountries(),
      getPrices(),
    ]);
    
    Login or Signup to reply.
  2. Using await on a Future<List<Cast>> will produce a List<Cast>. Therefore doing await Future.wait([await getCast()]); will try to call Future.wait with a non-Future, and that isn’t allowed.

    As @pskink mentioned, Future.wait returns a List of the returned values, which you could use:

    Future<void> callApi() async {
      var results = await Future.wait([
        getAdresses(),
        getCountries(),
        getPrices(),
        getCast(),
      ]);
    
      castMembers = results.last as List<Cast>;
    }
    

    Presumably getAdresses (sic), getCountries, getPrices, and getCast all return different types, so results will be the nearest common base type (probably Object or List<Object>), and you will need an explicit downcast. That’s a bit ugly, and it’s also slightly brittle since if you ever add new Futures to Future.wait call, you might need to adjust which element to access from results, and that would not be enforced at compile-time.

    Alternatively, you can use the approaches that I described in Dart Future.wait for multiple futures and get back results of different types:

    Future<void> callApi() async {
      await Future.wait([
        getAdresses(),
        getCountries(),
        getPrices(),
        getCast().then((members) => castMembers = members),
      ]);
    }
    

    which is one of the few cases where I’d use Future.then. Or wrap the assignment in a separate function to use pure asyncawait:

    Future<void> callApi() async {
      Future<void> initializeCastMembers() async {
        castMembers = await getCast();
      }
    
      await Future.wait([
        getAdresses(),
        getCountries(),
        getPrices(),
        initializeCastMembers(),
      ]);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search