David
David

Reputation: 3310

Taking inner observables when outer is complete

I'm new to RxJS so not even sure if I gave a proper title to a question.

To explain what I'm trying to achieve: I have one API endpoint which results in array of objects with ids. Then I will call another API endpoint with each id I got in array, in many calls. I want the data, subscriber of first API gets, to already include response of second API call.

StackBlitz: https://stackblitz.com/edit/rxjs-u45wvq

currently, values of thatThing are observables - and I want them to be the received objects.

Edit

I managed to achieve what I wanted, but it looks dirty in my opinion - since the solution uses Promise class to work it out.

https://stackblitz.com/edit/rxjs-d5ywen

I wander if there's RxJS way to do the same:

const source = fetchApi1().pipe(
  map(x => {
    return new Promise((yes, no) => {
      const s = x.array.map(m => fetchApi2(m.id))
      forkJoin(...s).subscribe(api2 => {
        x.array.forEach((row, i) => {
          row.thatThing = api2[i]
        })
        yes(x)
      })
    })
  }),
  switchMap(x => from(x))
);

Upvotes: 1

Views: 407

Answers (1)

martin
martin

Reputation: 96889

It's always better to avoid creating nested subscriptions so you can rewrite what you have into for example the following:

const source = fetchApi1().pipe(
  mergeMap(x => {
    const s = x.array.map((m: any) => fetchApi2(m.id)
      .pipe(
        map(response => {
          m.thatThing = response;
          return m;
        }),
      ));

    return forkJoin(s).pipe(mapTo(x));
  }),
);

Live demo: https://stackblitz.com/edit/rxjs-3nrc7g?file=index.ts

Upvotes: 1

Related Questions