Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge different HTTP calls which are dependent on each other in RxJS/Angular 6

Tags:

angular

rxjs

I've been trying to find this answer for a while now, but I, as a new person to RxJS and Angular (2+), am looking for a way to combine the results of two HTTP GET calls. Once one call has finished, a new call has to be done based on that result. The result of the first call will be combined with the second call. Preferably in a property which has an object as type.

I have been playing with mergeMap, switchMap and concatMap. According to the documentation and guides these functions should do what I want to achieve. But How?

In my example I have got an ID (3 for example). This is my code:

this.postsService.getPostData(postId)
.switchMap(
  postData => Observable.forkJoin(this.getUserByPostData(postData))
)
.subscribe( result => console.log(result) );

Both functions (getPostData and getUserByPostData) will return Observables due to http.get

In this case, especially due to forkJoin, I'd expect my result to be merged. However, the result which I retrieve has been completely replaced with the result of the second request (which is the one inside the switchMap function).

How would I be able to combine the results? Would it also be possible to push the results of the second HTTP request (this.getUserByPostData) as a property of the results of the first request?

like image 418
Stefan R Avatar asked May 15 '18 19:05

Stefan R


People also ask

What is the difference between switchMap mergeMap and concatMap?

Use mergeMap if you simply want to flatten the data into one Observable, use switchMap if you need to flatten the data into one Observable but only need the latest value and use concatMap if you need to flatten the data into one Observable and the order is important to you.

What is the difference between mergeMap and switchMap?

So here's the simple difference — switchMap cancels previous HTTP requests that are still in progress, while mergeMap lets all of them finish. In my case, I needed all requests to go through, as this is a metrics service that's supposed to log all actions that the user performs on the web page, so I used mergeMap .


1 Answers

If the second request depends upon data in the response from first request and if you want to combine the two responses, you can use a map operator within the switchMap:

this.postsService.getPostData(postId).switchMap(
  postData => this.getUserByPostData(postData).map(
    userByPostData => ({ postData, userByPostData })
  )
).subscribe(({ postData, userByPostData })=> console.log(postData, userByPostData));

Also, if the observable returned by the getPostData is HTTP-based, it will only ever emit once, so there will never be any need to switch. You could just use mergeMap, instead.

like image 66
cartant Avatar answered Oct 13 '22 22:10

cartant