
In modern Angular apps, it’s super common to make several API requests simultaneously and then act only after all responses come back. But how you manage this process can either keep your code clean and reliable or turn it into a tangled mess.
Some developers rely on manual flags to track when all calls finish — but this approach quickly becomes error-prone and hard to maintain.
The better way? RxJS’s forkJoin
operator.
Let’s walk through why forkJoin
is your friend, why flags aren’t, and how to implement this cleanly in your Angular apps. Ready? 🚀
The Challenge: Waiting for Multiple API Responses
Imagine your app needs to fetch data from three endpoints:
/api/user
/api/orders
/api/notifications
You want to wait until all three are done before proceeding.
If you try handling each response separately, using flags or counters, your code can quickly become messy and unreliable.
The Right Way: Using forkJoin
forkJoin
is built exactly for this scenario.
- It accepts multiple observables (your API calls).
- It waits for all to complete.
- Then emits an object or array with all the final results — all at once.
Here’s how it looks in Angular:
import { forkJoin } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html'
})
export class DashboardComponent implements OnInit {
constructor(private http: HttpClient) {}
ngOnInit() {
this.loadData();
}
loadData() {
const user$ = this.http.get('/api/user');
const orders$ = this.http.get('/api/orders');
const notifications$ = this.http.get('/api/notifications');
forkJoin({
user: user$,
orders: orders$,
notifications: notifications$
}).subscribe({
next: (response) => {
console.log('All responses received:', response);
// Use response.user, response.orders, response.notifications here
},
error: (error) => {
console.error('One or more API calls failed:', error);
}
});
}
}
Why this rocks:
- All calls run in parallel.
- You only act when everything is ready.
- Your code stays clean, concise, and easy to follow.
Why Flags Are a No-Go ❌
Some folks use manual flags to track API responses, like:
let userDone = false;
let ordersDone = false;
let notificationsDone = false;
this.http.get('/api/user').subscribe(() => {
userDone = true;
checkIfAllDone();
});
this.http.get('/api/orders').subscribe(() => {
ordersDone = true;
checkIfAllDone();
});
this.http.get('/api/notifications').subscribe(() => {
notificationsDone = true;
checkIfAllDone();
});
function checkIfAllDone() {
if (userDone && ordersDone && notificationsDone) {
console.log('All done!');
}
}
It works, but…
The Downsides:
- Manual state management = bug magnet. Forgetting to update a flag stalls your app forever.
- Hard to read and maintain. More APIs = more flags, more headaches.
- Race conditions lurk everywhere. Responses arrive at unpredictable times, and your flag logic can fail silently.
- No built-in error handling. You have to build it yourself, increasing complexity.
- Reinventing the wheel. RxJS offers tools made for this exact use case — don’t ignore them!
Pro Tip: Handling Partial Failures Gracefully
What if you want to proceed even if one API call fails?
No worries — just catch errors individually inside each observable before passing them to forkJoin
:
import { of, catchError } from 'rxjs';
const user$ = this.http.get('/api/user').pipe(catchError(() => of(null)));
const orders$ = this.http.get('/api/orders').pipe(catchError(() => of([])));
const notifications$ = this.http.get('/api/notifications').pipe(catchError(() => of([])));
forkJoin({ user: user$, orders: orders$, notifications: notifications$ })
.subscribe(response => {
console.log('Responses (with partial errors handled):', response);
});
This way, one failed call won’t break your entire flow.
Wrapping Up
- Use
forkJoin
to combine multiple API calls. It’s clean, safe, and easy to manage. - Say goodbye to manual flags and counters. They invite bugs and make your code harder to maintain.
- Handle partial errors inside observables for a more resilient app.
If this helped simplify your Angular API calls, don’t hesitate to like, share, or comment!
For more practical Angular and RxJS tips, follow me here on Medium — exciting stuff coming your way! 🚀