Learn RxJS
  • Introduction
  • Learn RxJS
    • Operators
      • Combination
        • combineAll
        • combineLatest
        • concat
        • concatAll
        • endWith
        • forkJoin
        • merge
        • mergeAll
        • pairwise
        • race
        • startWith
        • withLatestFrom
        • zip
      • Conditional
        • defaultIfEmpty
        • every
        • iif
        • sequenceEqual
      • Creation
        • ajax
        • create
        • defer
        • empty
        • from
        • fromEvent
        • generate
        • interval
        • of
        • range
        • throw
        • timer
      • Error Handling
        • catch / catchError
        • retry
        • retryWhen
      • Multicasting
        • publish
        • multicast
        • share
        • shareReplay
      • Filtering
        • audit
        • auditTime
        • debounce
        • debounceTime
        • distinct
        • distinctUntilChanged
        • distinctUntilKeyChanged
        • filter
        • find
        • first
        • ignoreElements
        • last
        • sample
        • single
        • skip
        • skipUntil
        • skipWhile
        • take
        • takeLast
        • takeUntil
        • takeWhile
        • throttle
        • throttleTime
      • Transformation
        • buffer
        • bufferCount
        • bufferTime
        • bufferToggle
        • bufferWhen
        • concatMap
        • concatMapTo
        • exhaustMap
        • expand
        • groupBy
        • map
        • mapTo
        • mergeMap / flatMap
        • mergeScan
        • partition
        • pluck
        • reduce
        • scan
        • switchMap
        • switchMapTo
        • toArray
        • window
        • windowCount
        • windowTime
        • windowToggle
        • windowWhen
      • Utility
        • tap / do
        • delay
        • delayWhen
        • dematerialize
        • finalize / finally
        • let
        • repeat
        • timeInterval
        • timeout
        • timeoutWith
        • toPromise
      • Full Listing
    • Subjects
      • AsyncSubject
      • BehaviorSubject
      • ReplaySubject
      • Subject
    • Recipes
      • Alphabet Invasion Game
      • Battleship Game
      • Breakout Game
      • Car Racing Game
      • Catch The Dot Game
      • Click Ninja Game
      • Flappy Bird Game
      • Game Loop
      • Horizontal Scroll Indicator
      • Http Polling
      • Lockscreen
      • Matrix Digital Rain
      • Memory Game
      • Mine Sweeper Game
      • Platform Jumper Game
      • Progress Bar
      • Save Indicator
      • Smart Counter
      • Space Invaders Game
      • Stop Watch
      • Swipe To Refresh
      • Tank Battle Game
      • Tetris Game
      • Type Ahead
      • Uncover Image Game
    • Concepts
      • RxJS Primer
      • Get started transforming streams with map, pluck, and mapTo
      • Time based operators comparison
      • RxJS v5 -> v6 Upgrade
Powered by GitBook
On this page
  • Transparently perform actions or side-effects, such as logging.
  • Why use tap?
  • Examples
  • Related Recipes
  • Additional Resources
  1. Learn RxJS
  2. Operators
  3. Utility

tap / do

PreviousUtilityNextdelay

Last updated 1 year ago

signature: tap(nextOrObserver: function, error: function, complete: function): Observable

Transparently perform actions or side-effects, such as logging.


💡 If you are using and old version of RxJS, tap used to be known as do!


Why use tap?

Think of tap as a surveillance camera in a shopping mall. It doesn't interfere with the shoppers (values) moving around but merely observes and records their actions. This operator is best for side effects: actions you want to take in response to values in an observable, without affecting the values themselves.

One of the superpowers of tap is its utility in debugging. When things aren't going as planned with your observable, instead of tearing apart your chain or inserting numerous logs, simply sprinkle in some tap operators. It's like adding checkpoints in a video game, helping you swiftly pinpoint issues without disrupting the main flow.

However, a word of caution: remember that tap is solely for side effects. If you find yourself tempted to modify data within a tap, it's generally best to resist. That's not its purpose, and you're better off with or other transformational operators in these cases.

Lastly, it's best to ensure that the side effects you introduce via tap are not critical to the main logic of your observable chain, keeping them non-intrusive and harmless.

Examples

Example 1: Logging with tap

( | | )

// RxJS v6+
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

const source = of(1, 2, 3, 4, 5);
// transparently log values from source with 'tap'
const example = source.pipe(
  tap(val => console.log(`BEFORE MAP: ${val}`)),
  map(val => val + 10),
  tap(val => console.log(`AFTER MAP: ${val}`))
);

//'tap' does not transform values
//output: 11...12...13...14...15
const subscribe = example.subscribe(val => console.log(val));

Example 2: Using tap with object

// RxJS v6+
import { of } from 'rxjs';
import { tap, map } from 'rxjs/operators';

const source = of(1, 2, 3, 4, 5);

// tap also accepts an object map to log next, error, and complete
const example = source
  .pipe(
    map(val => val + 10),
    tap({
      next: val => {
        // on next 11, etc.
        console.log('on next', val);
      },
      error: error => {
        console.log('on error', error.message);
      },
      complete: () => console.log('on complete')
    })
  )
  // output: 11, 12, 13, 14, 15
  .subscribe(val => console.log(val));

Related Recipes

Additional Resources


( )

📰 - Official docs

- In Depth Dev Reference

🎥 💵 - John Linquist

🎥 💵 - André Staltz

🎥 - Kwinten Pisman

📁 Source Code:

StackBlitz
Battleship Game
Breakout Game
Car Racing Game
Catch The Dot Game
Click Ninja Game
Flappy Bird Game
Horizontal Scroll Indicator
Lockscreen
Memory Game
Mine Sweeper Game
Platform Jumper Game
Save Indicator
Space Invaders Game
Stop Watch
Swipe To Refresh
Tank Battle Game
Tetris Game
Type Ahead
Uncover Image Game
tap
tap
Logging a stream with do
Utility operator: do
Build your own tap operator
https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/tap.ts
map
StackBlitz
jsBin
jsFiddle