mergeMap: nested calls
Create sequences of nested HTTP API calls

v.7

v.18

Fabio Biondi
Google Developer Expert
Microsoft MVP
# Introduction
In this lesson we will cover how to:
- avoid using nested subscriptions
- make sequential API calls using
mergeMap
- effectively handle three or more nested HTTP calls"
# Nested HTTP requests
Let's suppose we have an endpoint that retrieves information for a specific post.
Consider the following REST API:
This endpoint returns an object structured as follows:
The endpoint returns the post data including the id
of the user who wrote it (userId
).
We can then use this userId
in a subsequent call to retrieve the user’s information.
For example, the following endpoint can be used:
# Subscribe inside Subscribe
The first approach that usually comes to mind is:
1Subscribe to the first HttpClient.get()
2In the subscription, receive the data from the request and pass it to another HttpClient.get()
The following example shows exactly this mechanism but I warn you that it is absolutely a bad practice:
- we invoke the first endpoint to get the post information of the post whose
id
is 1
- The request returns the user post object that also contains the
userId
of the author
- In the subscription function we then subscribe to the second
HttpClient
too, using the userId
as part of the URL to get the user information
Nested subscription is a bad practice!
This pattern is often referred to as "callback hell" or "pyramid of doom," and in RxJS or reactive programming, it's considered a bad practice for a few reasons:
-
Nesting subscriptions leads to less readable and harder-to-maintain code.
As more asynchronous operations are chained, the code becomes deeply nested, difficult to understand, and tricky to handle errors properly.
-
Error Handling: since you have nested subscriptions, error handling becomes fragmented.
-
Unsubscribing Issues: handling unsubscription in nested subscriptions can be more complicated.
Each subscription is independent, so you have to track each of them to ensure proper cleanup, leading to potential memory leaks if not done correctly.
-
Loss of Composition: RxJS shines in its ability to compose observables with operators like switchMap
, mergeMap
, concatMap
, etc. (we'll talk about them later in the book), which allows you to flatten the code and keep everything within a single stream.
This lets you write cleaner, more maintainable code and avoids deeply nested subscriptions.
# map + mergeAll
This is an intermediate solution that I want to show you to better understand the final solution that I will propose later.
The first approach I want to show you is using the map
operator.
What kind of value do you think the subscription will receive?
It's an observable because we "transform" (using map
) the emitted Post response into another observable, a new HttpClient.get
.
It means that we should subscribe to it again in the subscribe
function but it does not change much from the previous solution and we have no advantages in terms of readability:
Our goal is to subscribe the observable directly inside the pipe
:
How can we achieve this?
mergeAll()
allows us to subscribe to the inner observable (the second this.http.get
) and merges its result into the outer stream.
As a result, the observable now emits the result of the second this.http.get
objects instead of the first one.
Here’s how to implement this mechanism in our example:
# nested calls with mergeMap