Understanding exhaustMap in Angular (RxJS)
In Angular (with RxJS), exhaustMap is an operator used to map values from a source Observable into inner Observables — but it ignores new emissions while the previous inner Observable is still running.
It is commonly used in form submissions, login requests, or button clicks where you want to prevent duplicate requests.
exhaustMap comes from the RxJS library, which Angular heavily uses for reactive programming.
How exhaustMap Works
When the source Observable emits a value:
It creates an inner Observable.
While that inner Observable is active:
Once the inner Observable completes:
Simple Example (Concept)
Imagine a Login button:
User clicks once → API call starts.
User clicks again quickly → ignored.
API completes → next click will work.
This prevents multiple API calls.
Syntax
source$.pipe(
exhaustMap(value => innerObservable$)
);
Angular Example (Login Button)
Component Example
import { Component } from '@angular/core';
import { fromEvent } from 'rxjs';
import { exhaustMap } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-login',
template: `<button #loginBtn>Login</button>`
})
export class LoginComponent {
constructor(private http: HttpClient) {}
ngAfterViewInit() {
const button = document.querySelector('button');
fromEvent(button!, 'click')
.pipe(
exhaustMap(() =>
this.http.post('https://api.example.com/login', {
username: 'test',
password: '123'
})
)
)
.subscribe(response => {
console.log('Login success', response);
});
}
}
What Happens Here?
First click → HTTP request starts.
Second click (before request finishes) → ignored.
After request completes → next click works.
Difference from Other Operators
| Operator | Behavior |
|---|
| mergeMap | Allows multiple inner Observables simultaneously |
| switchMap | Cancels previous inner Observable |
| concatMap | Queues them one by one |
| exhaustMap | Ignores new ones until current completes |
When to Use exhaustMap
✔ Login button
✔ Submit form
✔ Prevent duplicate API calls
✔ Prevent double payments
❌ When you need cancellation → use switchMap
❌ When you need queuing → use concatMap
Real-World Use Case (Form Submit in Angular)
this.formSubmit$
.pipe(
exhaustMap(formValue => this.apiService.saveData(formValue))
)
.subscribe();
If the user clicks submit multiple times rapidly:
Easy Way to Remember
exhaustMap = "Ignore until done."