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?
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.
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 .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With