To pipe each emitted value through a sequence of operators, we call the pipe method. Be sure to insert it before the subscribe.
Now we specify the operators. First let's transform the values.
Which operators do we use to transform the values ? If you said map, you are correct. We'll use map to transform the emitted value, multiplying it by 2.
The observable pipe method take any number of operators separated by commas.
Let's add a second map operator to transform the value again, subtracting 10. We now see the transformed items in the console.
from ([20, 15, 10, 5]).pipe(
map(item => item * 2),
map(item => item -10)
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
To log the originally omitted item as well, let's add a tap at the beginning of the sequence.
Now see our originally omitted item along with resulting transformed item.
Notice the 0 we see here in the result.
from ([20, 15, 10, 5]).pipe(
tap(item => console.log(`emitted item ... ${item}`)),
map(item => item * 2),
map(item => item -10),
map(item => {
if(item === 0){
throw new Error ('Zero detected');
}
return item;
})
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
Let's try error handling and add a check for 0. We'll use a map operator for our error handling. The map takes in the item. We want to execute multiple lines, we need a function body defined with curly braces. That turns our single line arrow function into a multi-line arrow function.
We'll use an if statement to check for a value of 0
and throw an error if a 0
is detected. Otherwise, we return the item.
Note that we need the
return
keyword in this case. One-line arrow function have implied return.
When we use a multi-line arrow function, we need and explicit return statement.
Take
lastly, let's add a take and take only three of the items. We no longer see our error. We take the first three items and complete before the item with the error is emitted.
from ([20, 15, 10, 5]).pipe(
tap(item => console.log(`emitted item ... ${item}`)),
map(item => item * 2),
map(item => item -10),
map(item => {
if(item === 0){
throw new Error ('Zero detected');
}
return item;
}),
take(3)
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
app.component.ts file
import { Component, VERSION, OnInit } from '@angular/core';
import {of, from, map, tap, take} from 'rxjs'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular ' + VERSION.major;
ngOnInit(){
from ([20, 15, 10, 5]).pipe(
tap(item => console.log(`emitted item ... ${item}`)),
map(item => item * 2),
map(item => item -10),
map(item => {
if(item === 0){
throw new Error ('Zero detected');
}
return item;
}),
take(3)
).subscribe({
next: (item) => console.log(`resulting item.. ${item}` ),
error: (err) => console.log(`error occoured ${err}`),
complete: () => console.log('Completed')
})
}
}
```
**Map operator internals**
```
import { Observable } from 'rxjs';
export function map(fn) {
// function
return (
input // takes an input Observable
) =>
new Observable((observer) => {
// creates an output Observable
return input.subscriber({
// subscribes to the input Observable
next: (value) => observer.next(fn(value)), // transform item using provided function and emits item
error: (err) => observer.error(err), // emits error notification
complete: () => observer.complete(), // emits complete notification
});
});
}
```
Top comments (0)