Martin
Martin

Reputation: 121

Adding list items in a Future in flutter returns no items

In flutter i read from the firebase database twice. The first code reads all references for a document found in an array. The next code goes thru all references and loads documentdata for that reference in firebase. When i debug, and as long i am in the forEach loop the rests array is filled. But as soon as the forEach loop is done, the rests list is empty? How can this be? What i want to do is continue to add data to the CustomerRestaurantsWithLunchCard = c to the list of restaraunts that exist in the class

  Future<CustomerRestaurantsWithLunchCard>
      customerRestaurantsWithLunchards() async {
    var c = await _service.document(
        path: APIPath.customerRestaurantsWithLunchCardsDocument(customerId),
        builder: (data, id) =>
            CustomerRestaurantsWithLunchCard.fromMap(data, id));

    var rests = new List<Restaurant>();

    c.myRestaurantsReferences.forEach((reference) {
      _service.document(
          path: (reference),
          builder: (data, id) => {
                rests.add(new Restaurant(
                  id: id,
                )),
              });
    });

    c.restaurants = rests;
    return c;
  }

Future<T> document<T>({
    @required String path,
    @required T builder(Map<String, dynamic> data, String id),
  }) {
    final reference = FirebaseFirestore.instance.doc(path);
    final snapshots = reference.get();
    return snapshots.then((value) => builder(value.data(), value.id));
  }

Upvotes: 0

Views: 69

Answers (2)

Martin
Martin

Reputation: 121

Found the answer in another thread Async/Await List.forEach

The new code is:

  Future<CustomerRestaurantsWithLunchCard>
      customerRestaurantsWithLunchards() async {
    var c = await _service.document(
        path: APIPath.customerRestaurantsWithLunchCardsDocument(customerId),
        builder: (data, id) =>
            CustomerRestaurantsWithLunchCard.fromMap(data, id));

    int noOfReferences = c.myRestaurantsReferences.length;

    for (var i = 0; i < noOfReferences; i++) {
      await _service.document(
          path: c.myRestaurantsReferences[i],
          builder: (data, id) => {c.restaurants.add(new Restaurant(id: id))});
    }
return c;

}

Upvotes: 0

cyberail
cyberail

Reputation: 1284

Add wait to second _service.document in foreach:

Future<CustomerRestaurantsWithLunchCard>
      customerRestaurantsWithLunchards() async {
    var c = await _service.document(
        path: APIPath.customerRestaurantsWithLunchCardsDocument(customerId),
        builder: (data, id) =>
            CustomerRestaurantsWithLunchCard.fromMap(data, id));

    List<Restaurant> rests = await new List<Restaurant>(); 
    await c.myRestaurantsReferences.forEach((reference) {
      await _service.document(
          path: (reference),
          builder: (data, id) => {
                rests.add(new Restaurant(
                  id: id,
                )),
              });
    });

    c.restaurants = await rests;
    return c;
  }

Upvotes: 1

Related Questions