5

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 Answer 1

7

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);
});
Sign up to request clarification or add additional context in comments.

3 Comments

"Property 'contact' does not exist on type 'undefined[]'" getting this error on const updatedProviders = [].contact([...p]);
You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. at subscribeTo (subscribeTo.js:28) <p> Getting this error on .subscribe even though the API calls are happening
Try this stackblitz with the code structure I posted: stackblitz.com/edit/angular-ivy-pyyjau. @jijo I corrected an issue with how I was flattening the array: it should be [].concat(...p);! Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.