DEV Community

Cover image for How to use mergeMap and forkJoin to handle multiple API requests in Angular 🚀
Manoj Prasanna  🚀
Manoj Prasanna 🚀

Posted on • Updated on

How to use mergeMap and forkJoin to handle multiple API requests in Angular 🚀

In this Article, I will explore the process of how to handle multiple API requests in Angular. Handling multiple API requests in Angular is a common scenario in modern web development. It's essential to implement an efficient and maintainable solution to avoid issues such as nested subscriptions. In this article, we will explore the proper way to handle multiple API requests using the mergeMap and forkJoin operators from the Angular RxJS library.

First of all, I will explain the problem.

problem because we are not using nested subscriptions

In the real world, it is common to make multiple API calls in our web applications. When navigating to a page, it is often necessary to retrieve data from various APIs. In Angular, the subscribe operator is typically used to fetch data from a single API call. However, when dealing with multiple API calls, there are more effective methods to implement this. We can initially solve the problem using the subscribe operator and then improve upon it by utilizing mergeMap and forkJoin.

Subscribe()

Normally, this technique is quite simple. However, when we trigger a new subscription for each and every value emitted by the Observable of call(), it can result in the creation of numerous unhandled Observables and Subscriptions. All of these entities remain in memory for the time being, leading to potential issues. Here is nested subscription example

export class DevToComponent implements OnInit {
    todoValue: string = '';
    comment: any;

    constructor(private http: HttpClient) { }

    ngOnInit(): void {

        this.retrieveDefaultData();
    }

    retrieveDefaultData(): void {
        this.http.get('https://jsonplaceholder.typicode.com/posts/1')
            .pipe(map(todo => todo[0]))
            .subscribe(
                todo => {
                    this.todoValue = todo;
                    this.http.get(`https://jsonplaceholder.typicode.com/posts/${this.todoValue}/comments`)
                        .subscribe(
                            coment => {
                                this.comment = coment;
                            }
                        );
                }
            )
    }

}
Enter fullscreen mode Exit fullscreen mode

It's important to note that when you subscribe() to an Observable multiple times, your subscribers won't listen to the exact same source. Instead, each subscription triggers a new copy of the defined Observable pipeline.

MergeMap()

This operator takes an input observable, applies a transformation function to each emitted value, and merges the resulting observables into a single output observable.By using MergeMap(), we can avoid nested subscriptions and achieve a more streamlined and efficient approach to handling asynchronous requests.

We can use the MergeMap() when we need data information from first API request to second API request:

export class DevToComponent implements OnInit {
    todoValue: string = '';
    comment: any;
    mergeMapResult: any;
    constructor(private http: HttpClient) { }

    ngOnInit(): void {
        this.retrieveDefaultData();
    }

    retrieveDefaultData(): void {
        this.http.get('https://jsonplaceholder.typicode.com/posts/1')
            .pipe(
                map(todo => {
                    return todo
                }),
                mergeMap(todo => this.http.get(`https://jsonplaceholder.typicode.com/posts/${todo}/comments`))
            ).subscribe(response => {
                this.mergeMapResult = response;
            })
    }

}
Enter fullscreen mode Exit fullscreen mode

Using mergeMap avoids nested subscriptions, you can avoid nested subscriptions and flatten the asynchronous operations. This leads to cleaner and more readable code, as the operations are executed sequentially instead of nesting multiple subscription callbacks.

ForkJoin()

This operator,when you have multiple parallel API requests that are independent of each other and you want to wait for all of them to complete before taking further action, you can use the forkJoin() operator instead of nested subscriptions.

We can use the ForkJoin() calling independent multiple API requests:

export class DevToComponent implements OnInit {
    todoValue: string = '';
    comment: any;
    firstApiResult: any;
    secondApiResult: any;
    constructor(private http: HttpClient) { }

    ngOnInit(): void {
        this.retrieveDefaultData();
    }

    retrieveDefaultData(): void {
        const firstAPI = this.http.get('https://jsonplaceholder.typicode.com/posts/1')
        const secondAPI = this.http.get(`https://jsonplaceholder.typicode.com/posts`)

        forkJoin([firstAPI, secondAPI]) //we can use more that 2 api request 
            .subscribe(
                result => {
                    //this will return list of array of the result
                    this.firstApiResult = result[0];
                    this.secondApiResult = result[1];
                }
            )
    }

}
Enter fullscreen mode Exit fullscreen mode

Using forkJoin() simplifies the handling of parallel API requests by providing a clean and efficient way to wait for all requests to complete. It eliminates the need for nested subscriptions, improving code readability and maintainability.

Note : Note that if any of the source observables in forkJoin() errors before completing, the entire observable will error and no result will be emitted. So, it's important to handle error cases appropriately when using forkJoin().

Conclusion
By adopting the use of mergeMap() and forkJoin() in RxJS, you have acquired a powerful technique for handling multiple API requests without resorting to nested subscriptions. This approach not only improves the readability and maintainability of your code but also allows for efficient parallel execution of asynchronous operations.

Thanks for reading the whole story ❤

Top comments (2)

Collapse
 
francittadini profile image
Francisco Cittadini

Thanks!

Collapse
 
vinhtin profile image
VinhTin-AQUA

wow, thank you so much