Skip to content
Advertisement

RxJS: Modify Observable array before subscribing

I’m fetching data (students via getStudents()) from an API which returns an Observable. Within this result I need to get data from two different tables and combine the result.

Here are my simplified interfaces:

export interface student Student {
   id: string
   name: string,
   school_id: string,
   classroom_id: string
}

export interface school School {
   id: string,
   name: string
}

export interface classroom Classroom {
   id: string,
   name: string
}

I now need to fetch all students and add the respective school and classroom for each student via the foreign keys school_id and classroom_id.

My current approach is something like the following. I know it’s unfinished but I can’t manage to find the right operator and how to properly use it.

this.getStudents().pipe(
   switchMap(students => {
      student.map(student => forkJoin([
         this.getSchool(student.school_id),
         this.getClassroom(student.classroom_id)
      ]))
   })
)

All of the methods (getStudents(), getSchool(), getClassroom()) return Observables. My goal is to get an array of students with the respective school and classroom data after subscription.

I know how to get it done if I need to fetch a single student (e.g. with getStudent()) and then use combineLatest to combine multiple streams. But when fetching multiple students it’s different.

Thank you in advance!

Advertisement

Answer

You need to forkJoin the observable array that you get from student.map() and use map to project the result into the required object.

const result$ = getStudents().pipe(
  switchMap((students: Student[]) =>
    forkJoin(students.map(student =>
      forkJoin([
        getSchool(student.school_id),
        getClassroom(student.classroom_id)
      ]).pipe(map(([school, classroom]) => ({
        student,
        school,
        classroom
      }))
    )
  ))
));
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement