Adrian Karr
Adrian Karr

Reputation: 147

Flutter async/await doesn't work inside forEach

I don't know what is missing here.. This is a function which is suppose to place orders from customers. The whole logic is quite simple :

If 1 single item in the cart , just executes once. If there are more, appends the order to the first order number. But for some reason its not waiting till the orderRepo.addOrder execution is complete initially.

  dynamic firstOrderNumber = 0;
  var existingOrder = false;

  void addOrder(List<Cart> carts) async {        --> Coming to add the list of orders
    carts.forEach((_cart) async {                --> Going to add each items in cart
      
             x += 1;
  print("\nVALUE of x inside addOrder = $x");     -> Adding X flag here to check
      Order _order = new Order();

      _order.productOrders = new List<ProductOrder>();
      _order.tax = _cart.product.store.defaultTax;
      _order.deliveryFee = payment.method == 'Pay on Pickup'
          ? 0
          : _cart.product.store.deliveryFee;
      OrderStatus _orderStatus = new OrderStatus();
      _orderStatus.id = '1'; 
      _order.orderStatus = _orderStatus;
      _order.deliveryAddress = payment.method == 'Pay on Pickup'
          ? new Address()
          : settingRepo.deliveryAddress.value;
      _order.hint = ' ';
      ProductOrder _productOrder = new ProductOrder();
      _productOrder.quantity = _cart.quantity;
      _productOrder.price = _cart.product.price;
      _productOrder.id = _cart.product.id;
      _productOrder.product = _cart.product;
      _productOrder.options = _cart.options;

      _order.productOrders.add(_productOrder);
      print("Current value of EXISTING : $existingOrder");
      if (!existingOrder) {
        print("\n\nEntering not existing order....\n");
        await orderRepo.addOrder(_order, this.payment).then((value) {      ---> Doesn't wait. PROBLEM
          if (value is Order) {
            print("The value is now $value");
            firstOrderNumber =
                value.id.toString(); //catching order number to append
            print("FIRSTORDERNUMBER : $firstOrderNumber");
            setState(() {
              loading = false;
            });
          }
        });
        print("Settting value of existing order now...");
        existingOrder = true;
        print("Existing order is now $existingOrder");
      }
      // print("Existing order is now $existingOrder");
      else {
        print("\n\nEntering existing order....\n");
        orderRepo
            .addAdditionalOrder(
                _productOrder, _cart, _order, firstOrderNumber, this.payment)
            .then((value) {
          if (value is Order) {
            setState(() {
              loading = false;
            });
          }
        });
      }
    });
  }

OUTPUT from console :

I/flutter ( 6925): VALUE of x inside addOrder = 1
I/flutter ( 6925): Current value of EXISTING : false
I/flutter ( 6925): Entering not existing order....
I/flutter ( 6925): VALUE of x inside addOrder = 2    ---> See the problem. It came back to increment X before the await is complete.  
I/flutter ( 6925): Current value of EXISTING : false
I/flutter ( 6925): Entering not existing order....   

//Now it is giving the result of the AWAIT which it should have waited for before.....

I/flutter ( 6925): The response of first order is : <JSON RESPONSE from first addOrder execution...coming late..>
I/flutter ( 6925): The value is now Instance of 'Order'
I/flutter ( 6925): FIRSTORDERNUMBER : 141
I/flutter ( 6925): Settting value of existing order now...
I/flutter ( 6925): Existing order is now true
I/flutter ( 6925): The response of first order is : 

Any hints ? How can i NOT EXECUTE ANYTHING ELSE UNTILL await orderRepo.addOrder(_order, this.payment).then((value) { is complete ??? Been doing trial n error for good few days

Upvotes: 2

Views: 1494

Answers (4)

Eray Hamurlu
Eray Hamurlu

Reputation: 783

that solved my issue.

for (var item in items) {
  await function(item);
}

Upvotes: 1

Henok
Henok

Reputation: 3383

Try map() like this


await Future.wait(carts.map((_cart)async{

  //your code here


}));

Upvotes: 3

Tipu Sultan
Tipu Sultan

Reputation: 1865

Instate of using then function simply use await.

if (!existingOrder) {
    print("\n\nEntering not existing order....\n");
    var value = await orderRepo.addOrder(_order, this.payment);
    if (value is Order) {
        print("The value is now $value");
        firstOrderNumber = value.id.toString();
        print("FIRSTORDERNUMBER : $firstOrderNumber");
        setState(() {
          loading = false;
        });
      }
    print("Settting value of existing order now...");
    existingOrder = true;
    print("Existing order is now $existingOrder");
  }

Upvotes: 0

Rohit Soni
Rohit Soni

Reputation: 1447

I think it should work for you!

myFunc() async {
  for(File file in files) {
    await saveFiles(file);
  }
}

Upvotes: 1

Related Questions