Angular multiple calls to same API in a loop

Viewed 6107

I have a requirement to iterate through an array of objects and make an API call for each object. Based on the number of objects in the response, I'm creating new objects and pushing into an array. Below is the sample code. For e.g., if there are 2 providers initially and each provider has 2 locations each, updatedProviderList will have 4 providers. This is working fine.

The problem is, updateProvidersInState has to be called only after all the API calls and the logic related to that are done. I have tried with the indices as shown below, but it doesn't work. Any ways to call the updateProvidersInState only after all the API calls are done ?

let providers = []; //assume this is already populated
let updatedProvider;
let updatedProviderList;
providers.forEach((prv, index) => {
  this.dataService.getLocation(prv.id).subscribe((response: LocationResults) => {
    response.locations.forEach((location, i) => {
      updatedProvider = cloneDeep(prv);
      updatedProvider.location = location;
      updatedProviderList.push(updatedProvider);
      if (index === providers.length - 1 && i === response.length - 1) {
        this.updateProvidersInState(updatedProviderList);
      }
    });
  });
});
1 Answers

The forkJoin() function allows you join a list of observables and continue once all requests complete. The benefit of this is that the requests will be made in parallel instead of sequentially.

import { forkJoin } from 'rxjs';

let providers: Provider[] = []; // assume this is populated, i made up the type Provider.

forkJoin(
  providers.map(p =>
    this.dataService.getLocation(p.id).pipe(
      // map each Location to a cloned provider object
      map((response: Location[]) => response.map(location => {
        const updatedProvider = cloneDeep(p);
        updatedProvider.location = location;
        return updatedProvider;
      }))
    )
  )
).subscribe((p: Provider[][]) => {
  // flatten the multi-dimensional array
  const updatedProviders = [].concat(...p);

  this.updateProvidersInState(updatedProviders);
});
Related