0

I have a parent observable and two child observables who are getting the trialId from parent response and do http calls on their own. I tried to use mergeMap but it gives me error that it's not a function. How could I do this ?

private _trialListPoll$ = timer(0, this.listRequestInterval).pipe(

    this.trialDataService.getTrailForPatient(this.patientId).mergeMap(
      (data) => {
        if (data.result.length > 0) {
          const trial = data.result[0] as TrialPhase;
          this.trialId = trial.trialId;
          this.trialStartDate = trial.startDate;
          this.trialEndDate = trial.endDate;
          this.trialData$.next(data.result[0]);
          this.loadDailyQuestionaireAnswerData(this.trialId); // child which makes http call and being subscribed somewhere
          this.loadStartEndQuestionaireData(this.trialId); // child which makes http call and being subscribed somewhere
        } else {
          this.trialStartDate = undefined;
          this.trialEndDate = undefined;
          this.trialData$.next(undefined);
        }
        this.isQuestionnaireInDateRange();
        this.isLoadingTrial$.next(false);
      }
    ),share());
Milo
  • 3,365
  • 9
  • 30
  • 44
tlq
  • 887
  • 4
  • 10
  • 21

1 Answers1

0

In general, you would do a nested call like this:

  todosForUser$ = this.http.get<User>(`${this.userUrl}/${this.userName}`)
    .pipe(
      switchMap(user =>
        this.http.get<ToDo[]>(`${this.todoUrl}?userId=${user.id}`)
      )
    );

In this example, we get the user by userName, then use the switchMap to get the related data using the retrieved user's id.

For multiple requests, you can do something like this:

Observable

  dataForUser$ = this.http.get<User>(`${this.userUrl}/${this.userName}`)
    .pipe(
      switchMap(user =>
        combineLatest([
          of(user),
          this.http.get<ToDo[]>(`${this.todoUrl}?userId=${user.id}`),
          this.http.get<Post[]>(`${this.postUrl}?userId=${user.id}`)
        ])
      ),
      map(([user, todos, posts]) => ({
        name: user.name,
        todos: todos,
        posts: posts
      }) as UserData)
    );

Interface for the set of data

export interface UserData {
  name: string;
  posts: Post[];
  todos: ToDo[];
}

This code retrieves the first set of data (so we have the userId from the username), then uses combineLatest to combine the latest values from each of the streams.

I have a stackblitz example here:

https://stackblitz.com/edit/angular-todos-deborahk

Hope this helps.

DeborahK
  • 57,520
  • 12
  • 104
  • 129