0

Hi I just recently discovered the power of forkjoins for APIs and trying to use it speed up load times. As the title says seeking help on best practice to run a forkjoin after a forkjoin.

I have a forkjoin which grabs some data for 2 x APIs. Based on the data is grabbed I need to run a 2nd forkjoin for an additional 2 x APIs.

In the first forkjoin for a given id I grab a form's data and UX style data.

const form = this.apiService.getForm(id);
const style = this.apiService.getFormStructure(id);

In the 2nd forkjoin I want to pass the photoIds found in the form data to 2 x APIS:

this.apiService.getPhotoUrls(photoIds)
this.apiService.getPhotoHistory(photoIds)

Here is what I have so far:

let formId: string = '1';
const form = this.apiService.getForm(id);
const style = this.apiService.getFormStructure(id);


forkJoin([form, style])
.subscribe(
 (data:Object[]) => {
   // handle result
   let formData = data[1];
   let formStyle = data[2];
   let photoIds:number[] = formData.photoIds;
   //***What is the best to pass the photo Ids to run the next 2 APIS??****//
 }
);

Thanks so much for the help in advance!

Ka Tech
  • 8,937
  • 14
  • 53
  • 78

1 Answers1

2

You're almost there. Use a higher order mapping operator like switchMap to switch from one observable to another. You could also skip the explicit formData and formStyle initializations using de-structuring assignment

forkJoin([form, style]).pipe(
  switchMap(([formData, formStyle]) => {
      let photoIds: number[] = formData['photoIds'];
      return forkJoin([
        this.apiService.getPhotoUrls(photoIds)
        this.apiService.getPhotoHistory(photoIds)
      ]);
  })
).subscribe({
  next: ([urls, history]) => {
    // `urls` - response from `apiService.getPhotoUrls(photoIds)`
    // `history` - response from `apiService.getPhotoHistory(photoIds)`
  },
  error: (error: any) => {
    // handle error
  }
});

Here is a brief comparison b/n forkJoin operator and switchMap function.

ruth
  • 29,535
  • 4
  • 30
  • 57
  • Thank you so much for the assistance. In regards to the error capture does this mean if any of the the APIs fails it will be immediately captured in error:? And all other API responses will be ignored (preferred) – Ka Tech Mar 01 '21 at 22:59
  • 1
    @KaTech: Yes in case of an error from any of the source observable, all the observables are closed and an error is emitted to the subscription. Though you need to note since all the observables are triggered in parallel it might happen one of the source is complete before an error, but nevertheless this value will not be emitted and only the error will be emitted. – ruth Mar 01 '21 at 23:12
  • Awesome I've began implementing i am already seeing my load times for the page reduce by half. Thanks again! – Ka Tech Mar 02 '21 at 00:13