RxJS Map, Tap and Take in Angular
Tags: javascript, rxjs, angular
Published: 2022-09-03 12:06:57

---
title: RxJS Map, Tap and Take in Angular
published: true
description: RxJS Map, Tap and Take in Angular
tags: javascript, rxjs, angular
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
---
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')
    })
```

![Omitted items](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ozliiivy8glvtwjy3x9.png)
To log the originally omitted item as well, let's add a tap at the beginning of the sequence.  

![tap example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s65qzazjxswrubs5bvi6.png)
Now see our originally omitted item along with resulting transformed item. 
![Zero detected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ctkarybzt3i5tzwqhmcy.png)

> 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. 

![zero detected resolved](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b8rpvxsvfjfmkeefh4vr.png)

**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')
    })
```
![Take example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugjyej4b21udr8x5cmyz.png)

**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
      });
    });
}

```