What is exhaustMap in angular with example

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:

  1. It creates an inner Observable.

  2. While that inner Observable is active:

    • Any new emissions from the source are ignored.

  3. Once the inner Observable completes:

    • It can accept the next source emission.

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

OperatorBehavior
mergeMapAllows multiple inner Observables simultaneously
switchMapCancels previous inner Observable
concatMapQueues them one by one
exhaustMapIgnores 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:

  • Only the first request runs.

  • Others are ignored until it completes.

Easy Way to Remember

exhaustMap = "Ignore until done."