0
0
AngularHow-ToBeginner · 4 min read

How to Use tap Operator in RxJS for Side Effects

Use the tap operator in RxJS to perform side effects such as logging or debugging inside an observable chain without modifying the emitted values. It takes a function that runs on each emission but passes the original data unchanged downstream.
📐

Syntax

The tap operator is used inside an RxJS pipe to run side-effect code on each emitted value without changing the stream.

  • tap(nextFn): Runs nextFn on each emitted value.
  • tap({ next, error, complete }): Runs callbacks for next value, error, and completion.
typescript
import { tap } from 'rxjs/operators';

observable$.pipe(
  tap(value => {
    // side effect code here
  })
);
💻

Example

This example shows how to use tap to log values emitted by an observable without changing them.

typescript
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

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

source$.pipe(
  tap(value => console.log('Before map:', value)),
  map(value => value * 10),
  tap(value => console.log('After map:', value))
).subscribe(finalValue => {
  console.log('Subscriber received:', finalValue);
});
Output
Before map: 1 After map: 10 Subscriber received: 10 Before map: 2 After map: 20 Subscriber received: 20 Before map: 3 After map: 30 Subscriber received: 30
⚠️

Common Pitfalls

Common mistakes when using tap include:

  • Trying to modify the emitted value inside tap. It does not change the stream data.
  • Using tap for asynchronous side effects without handling timing properly.
  • Confusing tap with map which transforms data.
typescript
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

// Wrong: modifying value inside tap (does NOT affect output)
const wrong$ = of(1).pipe(
  tap(value => { value = value * 10; }),
);

wrong$.subscribe(value => console.log('Wrong output:', value));

// Right: use map to transform values
const right$ = of(1).pipe(
  map(value => value * 10),
  tap(value => console.log('Right output:', value))
);

right$.subscribe();
Output
Wrong output: 1 Right output: 10
📊

Quick Reference

Use tap to:

  • Run side effects like logging or debugging.
  • Inspect values without changing them.
  • Handle next, error, and complete callbacks.

Remember: tap does not modify the stream data.

UsageDescription
tap(nextFn)Run a function on each emitted value without changing it
tap({ next, error, complete })Run callbacks for next value, error, and completion events
Use with pipe()Place inside observable pipe to add side effects
Do not modify valuestap should not change emitted data, use map for that

Key Takeaways

Use tap to perform side effects without altering the observable data.
tap runs a function on each emitted value inside the pipe.
Do not modify values inside tap; use map to transform data.
tap can handle next, error, and complete callbacks.
tap is great for logging and debugging observable streams.