Search code examples
rxjsangular2-observables

when to use tap() and when to use map() in RxJS


A the document describes the tap() with following code:

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

const clicks = fromEvent(document, 'click');
const positions = clicks.pipe(
  tap(ev => console.log(ev)),
  map(ev => ev.clientX),
);
positions.subscribe(x => console.log(x));

but I do not understand why to use tap. Is it just logging. The explanation says

Map every click to the clientX position of that click, while also logging the click event


Solution

  • Tap

    Perform a side effect for every emission on the source Observable, but return an Observable that is identical to the source

    Example:

    tap(value => console.log(value))
    

    Map

    Applies a given project function to each value emitted by the source Observable, and emits the resulting values as an Observable.

    Example:

    map(value => 'prefix' + value)
    

    Why not to use map or other operators for side effects like log

    You can use map, scan and any other operator that gets a function and returns an individual result to implement side effects. This will make your code very hard to understand/debug/find bugs in the future. Provided that, in general it is not good to use side effects in pipes. Logging can be an exception if you need/want it and don't want to have lot's of subscriptions for every logging point. Therefore tap can be useful. You could adapt this to the following steps:

    1. Try to avoid as many side effects as possible
    2. If you need some (logging) use tap to clarify that there is an side effect

    Example for how you could but should not

    switchMap(value => {
      console.log(value); // Side effect 1
      const newValue = foo(value);
      console.log(newValue); // Side effect 2
      return of(newValue);
    })
    

    Example of how you could do and should

    tap(console.log), // Side effect 1
    switchMap(value => of(foo(value))),
    tap(console.log) // Side effect 2
    

    Last word: When you write initially code that brings not much of an benefit. The larget your project gets and the moment other people try to find bugs it will improve saved time a lot.