0
0
AngularHow-ToBeginner · 4 min read

How to Use mergeMap in RxJS: Syntax, Example, and Tips

The mergeMap operator in RxJS maps each value from a source observable to an inner observable and merges all inner observables into a single observable. It is useful for handling multiple asynchronous tasks concurrently without waiting for each to complete before starting the next.
📐

Syntax

The mergeMap operator takes a function that returns an observable for each value emitted by the source observable. It subscribes to all inner observables and merges their outputs into one observable stream.

  • sourceObservable.pipe(mergeMap(value => innerObservable)): Transforms each source value into an inner observable.
  • value => innerObservable: Function returning an observable for each source value.
  • All inner observables run concurrently and their results are merged.
typescript
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

const source$ = of(1, 2, 3);

const result$ = source$.pipe(
  mergeMap(value => of(`Result: ${value}`))
);

result$.subscribe(console.log);
Output
Result: 1 Result: 2 Result: 3
💻

Example

This example shows how mergeMap handles multiple asynchronous calls concurrently. Each number from the source observable triggers a simulated API call that returns after a delay. The results appear as soon as each inner observable completes, regardless of order.

typescript
import { of } from 'rxjs';
import { mergeMap, delay } from 'rxjs/operators';

const source$ = of(1, 2, 3);

function fakeApiCall(id: number) {
  return of(`Response from API ${id}`).pipe(delay(1000 - id * 200));
}

source$
  .pipe(mergeMap(id => fakeApiCall(id)))
  .subscribe(console.log);
Output
Response from API 3 Response from API 2 Response from API 1
⚠️

Common Pitfalls

1. Confusing mergeMap with switchMap: mergeMap runs all inner observables concurrently, while switchMap cancels previous inner observables when a new value arrives.

2. Uncontrolled concurrency: Using mergeMap without limits can cause too many concurrent subscriptions, leading to performance issues.

3. Forgetting to return an observable: The function inside mergeMap must return an observable, not a plain value.

typescript
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

const source$ = of(1, 2, 3);

// Wrong: returns a plain value instead of observable
const wrong$ = source$.pipe(
  mergeMap(value => `Value: ${value}`) // This will cause an error
);

// Right: returns an observable
const right$ = source$.pipe(
  mergeMap(value => of(`Value: ${value}`))
);

right$.subscribe(console.log);
Output
Value: 1 Value: 2 Value: 3
📊

Quick Reference

FeatureDescription
PurposeMaps each source value to an inner observable and merges all outputs
ConcurrencyRuns all inner observables concurrently without canceling
Return valueAn observable that emits merged results from all inner observables
Common use caseHandling multiple async requests simultaneously
Difference from switchMapDoes not cancel previous inner observables

Key Takeaways

Use mergeMap to handle multiple async tasks concurrently by merging inner observables.
Always return an observable inside the mergeMap function to avoid errors.
Be aware that mergeMap does not cancel previous inner observables, unlike switchMap.
Limit concurrency if needed to prevent performance issues with too many simultaneous subscriptions.
Use mergeMap when you want all inner observables to run and emit results independently.