0

I'm new to Dart and therefore having trouble with asynchronous programming. I'm trying to loop through a list of elements (let's call them ingredients for now) and query the database for recipes which contain the ingredient. To achieve this, I have a list 'ingredientsSelectedList' and pass it over to a future which is supposed to query the Firestore Database and add the result to the 'possibleRecipes' List. The problem is, that I can't figure out how to 'await' the for loop to finish, before returning the 'possibleRecipes' List. Everytime I run it, it returns an empty list. Hope I didn't make it too complicated and Thanks in advance for everyone that's taking the time to read this :)

PS: I have spent hours to find a solution to this online, but couldn't find anything.

Future searchRecipe(ingredients) async {
    var possibleRecipes = []; //List to store results
    for (int i = 0; i < ingredients.length; ++i) {
      var currentIngredient = ingredients[i];
      //now query database for recipes with current ingredient
      var fittingRecipes = Firestore.instance
          .collection('recipes-01')
          .where('ingr.$currentIngredient', isEqualTo: true);
      fittingRecipes.snapshots().listen((data) => data.documents.forEach((doc) {
            possibleRecipes.add(doc['name']); //add names of results to the list
          }));
    }
    return possibleRecipes; //this returns an empty list
}
nicklbaert
  • 57
  • 2
  • 7

2 Answers2

0

Yes you can

Simply use this code

Future searchRecipe( List ingredients) async {
var possibleRecipes = []; //List to store results


 ingredients.forEach((currentIngredient) async{
//you can await anything here. e.g  await Navigator.push(context, something);
      //now query database for recipes with current ingredient
      var fittingRecipes = await Firestore.instance
          .collection('recipes-01')
          .where('ingr.$currentIngredient', isEqualTo: true);
      fittingRecipes.snapshots().listen((data) => data.documents.forEach((doc) {
            possibleRecipes.add(doc['name']); //add names of results to the list
          }));
    });
    return possibleRecipes; //this returns an empty list
}
Constantin N.
  • 2,739
  • 2
  • 16
  • 27
  • But the question author needs to keep in mind that the function is nevertheless a Future so the Caller will in any way get a future back no matter what is done inside. – Logemann Oct 25 '19 at 17:27
  • Thank you for taking the time to help an unexperienced newbie :D Unfortunately the function still returns an empty list :/ I think it's due to the fact that the return get's called before the forEach loop is completed. Do you know any way to fix this? Thanks again for helping me :) – nicklbaert Oct 25 '19 at 20:10
  • @nicklbaert you need to use for loop and call method which return Future and make that method async it will always wait for first method return before moving to next counter https://stackoverflow.com/a/70065572/5219642 see this answer – Amit Jul 18 '23 at 15:18
-1

put this in default flutter project on click event someFunc() and see the magic

   someFunc() async {
    for(int xq in x) {
     print("printing the loop value $xq");
     await functionThatReturnsAFuture(xq);
   }
  }

   functionThatReturnsAFuture(int x) async {
     await Future.delayed(const Duration(seconds: 2), (){

  setState(() {
    // This call to setState tells the Flutter framework that something has
    // changed in this State, which causes it to rerun the build method below
    // so that the display can reflect the updated values. If we changed
    // _counter without calling setState(), then the build method would not be
    // called again, and so nothing would appear to happen.
    _counter++;
  });

});
print("printing the loop value $x");
 }
Amit
  • 468
  • 5
  • 16