LAXO
LAXO

Reputation: 59

ForEach wait for Observable Subscription

I have this array orderCodes that has the codes for specific orders, and then with the code I can get the details of that order (each order has multiple products), and I need to extract the code of each product inside the order details.

The getOrderDetails()is an Observable with results(an array of the products), and each resulthas a code which is what I need.

    this.orderCodes.forEach((orderCode) => {

      loadOrderDetails(orderCode);

      getOrderDetails().subscribe((order: any) => {
        if (order.results) {
          order.results.map((result) => {
            console.log(result.code);
          });
        }
      });

    });

I've tried with this forEach but since I'm subscribing to the Observable the forEach skips to the next iteration and I need it to wait

Any ideas?

Upvotes: 0

Views: 1791

Answers (1)

Andrei
Andrei

Reputation: 12206

rxjs way would be

from(this.orderCodes).pipe(
  concatMap((orderCode) =>  // concatMap operator makes your items come "in order" one after another
    defer(() => {
      loadOrderDetails(orderCode);

      return getOrderDetails();

    }))
).subscribe((order: any) => {
  if (order.results) {
    order.results.map((result) => {
      console.log(result.code);
    });
  }
});

or you could convert to promises and use async await (more elegant, but usually less prefered way in angular because of converting to promises and change detection issues if done wrong, but it depends...)

async myFunctionThatDoesAllThis(...) {
....
for(let orderCode of this.orderCodes) {
  loadOrderDetails();
  const order = await getOrderDetails().pipe(take(1)).toPromise(); // pipe(take(1)) could be skipped if getOrderDetails is just an http request.
  if(order.results) {
     order.results.forEach((result) => {
        console.log(result.code);
     });
  }
}

Upvotes: 1

Related Questions