The Angular Tap RxJs operator returns an observable that is identical to the source. It does not modify the stream in any way. Tap operator is useful for logging the value, debugging the stream for the correct values, or perform any other side effects.
Syntax
1 2 3 | tap(nextOrObserver: function, error: function, complete: function): Observable |
Tap Operator Example
In the following example, we create an observable using the of operator. We use the pipe to chain the tap operator, which just logs the values of the source observable into the console.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | import { Component, VERSION } from "@angular/core"; import { tap } from "rxjs/operators"; import { of } from "rxjs"; @Component({ selector: "my-app", template: ` <h1>Tap Example</h1> `, styleUrls: ["./app.component.css"] }) export class AppComponent { ngOnInit() { of(1, 2, 3, 4, 5) .pipe( tap(val => { console.log("Tap " + val); }) ) .subscribe(val => console.log("at Subscriber " + val)); } } ***Console Tap 1 at Subscriber 1 Tap 2 at Subscriber 2 Tap 3 at Subscriber 3 Tap 4 at Subscriber 4 Tap 5 at Subscriber 5 |
if we simply pass the console.log
function to the tap operator and the results will be same.
1 2 3 4 5 | of(1, 2, 3, 4, 5) .pipe(tap(console.log)) .subscribe(val => console.log("at Subscriber " + val)); |
Tap does not modify the source observable in any way
For Example changing the source any way in the tap operator as in the example below, will have no effect.
1 2 3 4 5 6 7 8 9 10 11 | of(1, 2, 3, 4, 5) .pipe( tap(val => { val=val+1 console.log("Tap " + val); return val; }) ) .subscribe(val => console.log("at Subscriber " + val)); |
Debugging the Observable
One of the use cases for the tap operator is using it to debug the Observable for the correct values.
The map operator in the following example, adds 5 to the source observable. To debug it, we can add the two tap operators. One before and one after it and inspect the values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | of(1, 2, 3, 4, 5) .pipe( tap(val => { console.log("before " +val); }), map(val => { return val + 5; }), tap(val => { console.log("after " +val); }) ) .subscribe(val => console.log(val)); **Console** before 1 after 6 6 before 2 after 7 7 before 3 after 8 8 |
Error & Complete callbacks
We can also use the tap operator to log the error and complete callbacks as shown in the example below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | import { Component, VERSION } from "@angular/core"; import { FormControl, FormGroup } from "@angular/forms"; import { debounce, map, tap } from "rxjs/operators"; import { interval, of, Subscription } from "rxjs"; @Component({ selector: "my-app", template: ` <h1>Tap Example</h1> `, styleUrls: ["./app.component.css"] }) export class AppComponent { ngOnInit() { of(1, 2, 3, 4, 5) .pipe( tap(val => { console.log("Before " + val); }), map(val => { if (val == 3) { throw Error; } return val + 5; }), tap( val => { console.log("After " + val); }, err => { console.log("Tap Error"); console.log(err); }, () => { console.log("Tap Complete"); } ) ) .subscribe(val => console.log(val)); } ngOnDestroy() {} } ***Console *** Before 1 After 6 6 Before 2 After 7 7 Before 3 Tap Error Æ’ Error() ERROR Æ’ Error() |
Reference
Read More