Search code examples
angularrxjsobservablengrxangular-httpclient

Angular RxJS combine multiple dependant GET requests when first request returns


Let's say I have a Student with two properties: courseIds, courses.

export interface IStudent {
  courseIds: number[];
  courses: ICourse[];
}

export interface ICourse {
  name: string;
}

When the page loads I issue a GET request to retrieve a Student where only the courseIds are populated. Then I want to validate these Id's and make an unknown number of aditional GET requests to a diferent endpoint to retrieve his Courses.
In the end I want to have a Student object with populated Courses array.

I got this far:

httpClient.get<IStudent>(url)
  .pipe(
    map(student => {
      const validIds = [];
      student.courseIds.forEach(id => {
        if (isValid(id)) {
          validIds.push(id);
        }
      }
      return validIds;
    }),
    ???
  ).subscribe(
    ???
  );

Question marks indicate where I'm stuck. How can I implement this using Observables?


Solution

  • In your pipe you can map and filter your valid id's before using switchMap and forkJoin to get an array of ICourse back.

    httpClient.get<IStudent>(url)
      .pipe(
        map(student => student.courseIds.filter((id: number) => isValid(id))),
        switchMap((ids: number[]) => forkJoin(ids.map(id => httpClient.get<ICourse>(id))))
      )
      .subscribe({
        next: (data: ICourse[]) => {
          /* use your course array */
          console.log(data)
        },
        error: (error) => console.log(error),
      }
    );
    

    You would probably want to split the http service classes up so you have clean 'gets' and do the stitching in a component service class. Then you just need to subscribe or use the async pipe in the component.

    StackBlitz Example