How to use Angular Observable pipe()

How to use Angular Observable pipe()

RxJS’ pipe() is both a standalone function and a method on the Observable interface that can be used to combine multiple RxJS operators to compose asynchronous operations. The pipe() function takes one or more operators and returns an RxJS Observable.

pipe can be used as a standalone method, which helps Angular developers reuse it at multiple places or as an instance method. This article will explain what pipe is and how to use it in an Angular Application. Additionally, it will show you examples of pipe using map ,filter & tap operators.

RxJs Operators

The operators are an important part of the Rxjs library. They are functions that take an observable as input and transforms it into a new observable without changing the original observable.

In other words, Operator takes in the values from one Observable, and creates a new Observable that emits altered values of the original Observable’s values, without affecting the original Observable.

For Instance:

Map operator takes an observable source as input. It applies a project function to each of the values emitted by the source observable and transforms it into a new value. It then emits the new value to the subscribers.

Filter operator filters items from the source observable based on some condition and returns the filtered value that satisfies the condition as a new observable and ignores the rest.

Map RxJs Operator

The following table shows some of the commonly used RxJS operators;

RxJs Commonly used Operators

Using pipe to combine operators

The pipe method accepts operators such as filter, map, mergeMap, as arguments. Each argument must be separated by a comma. The order of the operators is important because when a user subscribes to an observable, the pipe executes the operators in a sequence in which they are added.

Can be used in two ways. One as an instance of observable and the other way is to use it as a standalone method.

To use observable you need to import it from the rxjs library. If you intend to use the pipe standalone function, then you also need to import it as well. All the operators are available in the library rxjs/operators.

import { Observable, of, pipe} from ‘rxjs’;  
import { map, filter, tap } from ‘rxjs/operators’

Pipe as an instance method

pipe as an instance method is used as shown below. The operators op1, op2 etc are passed as the arguments to pipe method. The output of op1 method becomes input of the op2 operator and so forth.

obs.pipe(  
 op1(),

 op2(),

 op3(),

 op3(),

)

Here is the example of using pipe with map & filter operator.

import { Component, OnInit } from '@angular/core';  
import { Observable, of} from 'rxjs';  
import { map, filter, tap } from 'rxjs/operators'

@Component({  
 selector: 'app-root',  
 templateUrl: './app.component.html',  
 styleUrls: \['./app.component.css'\]

})

export **class** AppComponent implements OnInit {

obs = **new** Observable((observer) => {  
 observer.next(1)  
 observer.next(2)  
 observer.next(3)  
 observer.next(4)  
 observer.next(5)  
 observer.complete()  
}).pipe(  
 filter(data => data > 2),                  *//filter Operator* map((val) => {**return** val **as** number \* 2}),    *//map operator  
*)

data = \[\];

ngOnInit() {  
 **this**.obs1.subscribe(  
  val => {  
   console.log(**this**.data)  
}

)

}

}

//result

\[6, 8, 10\]

Here is the example of using Pipe with Map, Filter & Tap operator.

The following example makes use of pipe with map, filter & tap operator. RxJS tap() operator is a utility operator that returns an observable output that is identical to the source observable but performs a side effect for every emission on the source observable. It is used mostly for debugging purposes ( for example for logging the values of observable as shown below).

import { Component, OnInit } from '@angular/core';  
import { Observable, of, pipe } from 'rxjs';  
import { map, filter, tap } from 'rxjs/operators'  


@Component({  
 selector: 'app-root',  
 templateUrl: './app.component.html',  
 styleUrls: \['./app.component.css'\]  
})

export **class** AppComponent implements OnInit {

obs = **new** Observable((observer) => {  
 observer.next(1)  
 observer.next(2)  
 observer.next(3)  
 observer.next(4)  
 observer.next(5)  
 observer.complete()  
}).pipe(  
 tap(data => console.log('tap '+data)),           *//tap  
* filter(data => data > 2),                        *//filter  
* tap(data => console.log('filter '+data)),        *//tap  
* map((val) => { **return** val **as** number \* 2 }),      *//map  
* tap(data => console.log('final '+data)),         *//tap*

)

data = \[\];  


ngOnInit() {  
**this**.obs.subscribe(  
 val => {  
 **this**.data.push(val)  
   console.log(**this**.data)  
}

)

}

}

Pipe as a stand alone method

pipe can be used as a standalone function to compose operators and re-use the pipe at other places.

For example:

import { Component, OnInit } from '@angular/core';  
import { Observable, of, pipe } from 'rxjs';  
import { map, filter, tap } from 'rxjs/operators'  


@Component({  
 selector: 'app-root',   
 templateUrl: './app.component.html',  
 styleUrls: \['./app.component.css'\]

})

export **class** AppComponent implements OnInit {

customOperator = pipe(  
 tap(data => console.log('tap '+data)),  
 filter(data => data > 2),  
 tap(data => console.log('filter '+data)),  
 map((val) => {   
 **return** val **as** number \* 2  
}),  
 tap(data => console.log('final '+data)),  
);  


obs = **new** Observable((observer) => {  
 observer.next(1)  
 observer.next(2)  
 observer.next(3)  
 observer.next(4)  
 observer.next(5)  
 observer.complete()  
}).pipe(  
 **this**.customOperator,  
 tap(data => console.log('final '+data)),  
)  


data = \[\];  


ngOnInit() {  
 **this**.obs.subscribe(  
 val => {  
  **this**.data.push(val)  
   console.log(**this**.data)

}

)

}

}

The stand alone pipe can be used as shown below:

customOperator = pipe(  
 tap(data => console.log('tap '+data)),  
 filter(data => data > 2),  
 tap(data => console.log('filter '+data)),  
 map((val) => {  
  **return** val **as** number \* 2  
}),  
 tap(data => console.log('final '+data)),

);

obs = **new** Observable((observer) => {  
 observer.next(1)  
 observer.next(2)  
 observer.next(3)  
 observer.next(4)  
 observer.next(5)  
 observer.complete()  
})

ngOnInit() {  
 **this**.customOperator(**this**.obs).subscribe();  
}

References

  1. RxJs Library
  2. Operators
  3. Pipe API
  4. Map API
  5. Tap API
  6. Filter API

Read my previous article here and follow me for more more articles on Angular.