Angular - Proper way to call procedure after async call to backend

Viewed 156

i have a bit of situation with executing procedure after async call to backend api

this.includedServicesList.forEach(x =>
          this.ccApi.getServicePrice(x.ServiceCode, '0', 'NONE')
            .subscribe(data => {
              x.ServicePrice = data.MPrice;
              this.includedServicesPrice += data.MPrice;
              //this.calculatePrices();
            })
        );
        //this.calculatePrices();

For each element of array I need to call backend api (get some data from database).

After that is done I would like to call calculatePrices procedure to update data. If I put procedure call after forEach loop, it just gets executed before data is even gathered. If I put it inside subscribe block, it gets called once for each element in array (and I need it called only once after entire loop is done)

Is there any good way to solve this (without setting random timeouts and hoping all async calls will be done by that point or stuff like that)

Thank you in advance

2 Answers

You can leverage zip operator.

After all observables emit, emit values as an array

import { zip } from 'rxjs';

zip(
   this.includedServicesList.map(x =>
      this.ccApi.getServicePrice(x.ServiceCode, '0', 'NONE')
         .pipe(tap(data => {
            x.ServicePrice = data.MPrice;
            this.includedServicesPrice += data.MPrice;
         }))
   )
).subscribe(()=>this.calculatePrices())

the part

data => {
            x.ServicePrice = data.MPrice;
            this.includedServicesPrice += data.MPrice;
         }

Would be called after each response received. calculatePrices would be called when all the responses received.

I dont know if this work, because I cant see your backend call, but maybe you can provide instead of just one element to your service function, the entire array. Your serivce function then handles an entire array and returns then an array of prices, so you just have to make one call and dont have to wait for all the other calls. I hope you get what I mean. If not let me know!

Related