Angular RxJS tap
November 19, 2018
This page will walk through Angular RxJS tap
example. RxJS tap
performs side effects for every value emitted by source Observable
and returns an Observable
identical to the source Observable
until there is no error. tap
is the pipeable operator and it is the changed name of the RxJS do
operator. Angular 6 uses RxJS 6 that has been shipped with pipeable operators which can be used independent of an Observable
. To avoid the conflict with JavaScript keyword, some RxJS operators name has been changed such as do
changed to tap
, catch
changed to catchError
, switch
changed to switchAll
and finally
changed to finalize
. These operators are imported from rxjs/operators
. For example tap
is imported as following.
import { tap } from 'rxjs/operators';
tap
, are used within pipe
function of Observable
. tap
performs side effects only when the Observable
returned by tap
is subscribed. tap
can be used to debug values emitted by Observable
or to perform any side effect.
Technologies Used
Find the technologies being used in our example.1. Angular 7.0.0
2. Angular CLI 7.0.3
3. TypeScript 3.1.1
4. Node.js 10.3.0
5. NPM 6.1.0
6. RxJS 6.3.3
tap
tap
is a RxJS pipeable operator that returns identical Observable
as source Observable
and can be used to perform side effect such as logging each values emitted by source Observable
. tap
is declared as following.
public tap(nextOrObserver: Observer | function, error: function, complete: function): Observable
tap
has three optional parameters.
nextOrObserver: A normal
Observable
object to perform side effect.
error: Callback for errors in source
Observable
.
complete: Callback for completion of the source.
Find the sample example.
of(1, 2, 3, 4).pipe( tap(el => console.log("Process "+ el), err => console.error(err), () => console.log("Complete") ), filter(n => n % 2 === 0) ).subscribe(el => console.log("Even number: "+ el));
Process 1 Process 2 Even number: 2 Process 3 Process 4 Even number: 4 Complete
tap
is logging each value emitted from source Observable
. Second callback is to log error but there is no error in source Observable
hence error is not logged. Third callback is logging the message of completion that all values have been emitted from source Observable
.
As the parameters of the
tap
is optional, we can also use tap
as following.
of(1, 2, 3, 4).pipe( tap(el => console.log("Process "+ el)), filter(n => n % 2 === 0) ).subscribe(el => console.log("Even number: "+ el));
tap
multiple times to debug values at different stages. Find the sample code snippet.
of(1, 2, 3, 4).pipe( tap(el => console.log(el)), filter(n => n % 2 === 0), tap(el => console.log(el)), map(n => n + 10), tap(el => console.log(el)), scan((sum, n) => sum + n), tap(el => console.log(el)) ).subscribe(result => console.log("Result: "+ result));
Complete Example
tap-demo.component.tsimport { Component, OnInit } from '@angular/core'; import { Observable, of } from 'rxjs'; import { tap, map, filter, retry, catchError } from 'rxjs/operators'; import { TapDemoService } from './tap-demo.service'; @Component({ selector: 'app-tap-demo', templateUrl: './tap-demo.component.html' }) export class TapDemoComponent implements OnInit { stdNames$: Observable<string[]>; countryName$: Observable<string>; countryStates: string[]; constructor(private mapDemoService: TapDemoService) { } ngOnInit() { this.getStdNames(); this.getCountryName(); this.getCountryStates(); of(1, 2, 3, 4).pipe( tap(el => console.log("Process "+ el), err => console.error(err), () => console.log("Complete") ), filter(n => n % 2 === 0) ).subscribe(el => console.log("Even number: "+ el)); let cities = ["Varanasi", "Mathura", "Ayodhya"]; of(cities).pipe( tap(c => console.log(c.length)), map(dataArray => dataArray.join(", ")) ).subscribe(res => console.log(res)); } getStdNames() { this.stdNames$ = this.mapDemoService.getStdNames().pipe( tap(std => console.log(std)), map(res => res.split(",")) ); } getCountryName() { this.countryName$ = this.mapDemoService.getCountry().pipe( tap(cname => console.log("Accessing country name...")), map(country => country.getCountryName()), tap(cname => console.log(cname)), catchError(err => { console.error(err); return of(""); }) ); } getCountryStates() { this.mapDemoService.getCountry().pipe( retry(2), tap(cname => console.log("Accessing country states...")), map(country => country.getCountryStates()), tap(states => console.log(states)), catchError(err => { console.error(err); return of([]); }) ) .subscribe(res => this.countryStates = res); } }
<b>Student Names</b> <ul> <li *ngFor="let name of stdNames$ | async" > {{name}} </li> </ul> <b>Country Name</b> <div *ngIf="countryName$ | async as myCountryName"> {{myCountryName}} </div> <b>Country States</b> <ul> <li *ngFor="let state of countryStates" > {{state}} </li> </ul>
import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { MyCountry } from './my-country'; @Injectable({ providedIn: 'root' }) export class TapDemoService { getStdNames(): Observable<string> { return of("Mahesh, Krishna, Ram"); } getCountry(): Observable<MyCountry> { return of(new MyCountry()); } }
export class MyCountry { getCountryName() { return "India"; } getCountryStates() { return ["UP", "MP", "Assam", "Kerla"]; } }
import { Component } from '@angular/core'; @Component({ selector: 'app-root', template: ` <app-tap-demo></app-tap-demo> ` }) export class AppComponent { }
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { AppComponent } from './app.component'; import { TapDemoComponent } from './tap-demo.component'; import { TapDemoService } from './tap-demo.service'; @NgModule({ imports: [ BrowserModule, HttpClientModule, FormsModule, ], declarations: [ AppComponent, TapDemoComponent ], providers: [ ], bootstrap: [ AppComponent ] }) export class AppModule { }
Run Application
To run the application, find the steps.1. Download source code using download link given below on this page.
2. Use downloaded src in your Angular CLI application. To install Angular CLI, find the link.
3. Run ng serve using command prompt.
4. Access the URL http://localhost:4200
Find the print screen of the output.

References
RxJS tapAngular: The RxJS library
Pipeable Operators