danday74
danday74

Reputation: 57165

RxJs equivalent of promise chain

When chaining API calls with promises I do this:

this.http.get('/api/hello').toPromise().then(res => {
  return this.http.get('/api/there/' + res.id).toPromise()
}).then(res => {
  console.log('res from 2nd call', res)
}).catch(err => {
  console.log('err', err)
})

How do you chain API calls like this using Observables, when the 2nd response needs data from the 1st response before it can be made?

TIA

Upvotes: 1

Views: 2040

Answers (3)

User3250
User3250

Reputation: 3421

mergeMap is an option:

this.http.get(/api/hello')
    .pipe(mergeMap((s) => {
        return s;
    }),
    mergeMap((res) =>{
      const url ='/api/there/' + res.id;
      return this.http.get(url).pipe(map((res) =>   {
            return res;
        }));
    }))
    .subscribe(res => {
        console.log(res);//final response
    }, 
    undefined,
    () => console.log('complete'));

Demo here: https://stackblitz.com/edit/angular-xwsltm

Upvotes: 1

Felix Lemke
Felix Lemke

Reputation: 6488

Use switchMap to execute another http.get after the first pushes data. switchMap has the advantage that it cancels all pending inner requests when the parent pushes new data.

const request$ = this.http.get('pathto/api').pipe(
  switchMap((res) => {
    return this.http.get(`another/api/${res.id}`)
  })
);

request$.subscribe(innerRequestData => {
  // do whatever you want
});

Don't forget to subscribe, since otherwise it is a cold observable.

Upvotes: 1

Vivek Kumar
Vivek Kumar

Reputation: 5040

You should use flatMap Please visit this url https://stackblitz.com/edit/angular-6-rxjx-stuff. I have created this project for testing RxJS.

You can see the below function.

  test__flatMap() {
    const post$ = this.getPosts();
    const users$ = this.getUsers();
    const users2$ = this.getUsers();

    post$.pipe(
      flatMap(data => {
        console.log('data 1 >>> ', data);
        return users$;
      }),
      flatMap(data => {
        console.log('data 2 >>> ', data);
        return post$;
      }),
    ).subscribe(data => { console.log(`In the end >>> `, data); });
  }

Upvotes: 4

Related Questions