Home > Software engineering >  How to combine several futures into one in flutter
How to combine several futures into one in flutter

Time:04-25

I am making a shopping app. In the products i have given a few tabs of different types of products which are being received from the api. I want to add another tab of 'All' which displays all the products in all other tabs together. All the APIs are being called with id of each tab title and are identical in structure. Online i could find a few answers regarding future.wait but i don't think it will work in this case because they talk about completing one task after another which is what i want but i want to combine the results too. Basically, how to combine all of these identical futures into one single future to be passed into futurebuilder or is there a workaround to this problem?

Edit: I am getting my List of futures like this:-

for (int i = 0;i <Length;i  ) {

ProductsList.add(CollectionProductServices().getCategories(collectionModel.childPackages[i].id.toString()));

  }

CodePudding user response:

Your solution is using Future.wait :

FutureBuilder(
    future: Future.wait([
         firstFuture(), // Future<List<product>> 
         secondFuture(),// Future<List<product>> 
         //... More futures
    ]),
    builder: (
       context, 
       // results of all futures above
       AsyncSnapshot<List<List<product>>> snapshot, 
    ){

       // Check hasData once for all futures.
       if (!snapshot.hasData) { 
          return CircularProgressIndicator();
       }

       // Merge lists into one list 
         final List<product> result = [...snapshot.data[0], ...snapshot.data[1]];
       

       return Container();

    }
);

CodePudding user response:

you could simply use wait and expand

 final ress = await Future.wait([
    for (int i = 0;i <Length;i  ) 
        CollectionProductServices().getCategories(collectionModel.childPackages[i].id.toString());
  ]);

  final allProduct =  ress.expand((element) => element).toList();

and you could use map insted of for like

 final categoriesFuture =  Future.wait<List>(
   collectionModel.childPackages.map((item)=>   CollectionProductServices().getCategories(item.id.toString()) );
 );

but i don't things this is a good solution as we get each Categories twice one for it's tab and other for all Categories tab

you should get it only once and combine the same result somethings like

then use categoriesFuture,allProduct for displaying

  // inside initState or class
 final List<Future> categoriesFuture =  
   collectionModel.childPackages.map((item)=>   CollectionProductServices().getCategories(item.id.toString()) );
  
final allProduct =  Future.wait(categoriesFuture).then((value) => value.expand((element) => element).toList()) ;


//inside build method:
Column(
    children: [
      for (var item in categoriesFuture) 
        FutureBuilder(future: item,)
    ]);

FutureBuilder(future: allProduct,)
  • Related