In this tutorial, we will learn how to use the RxJS map() operator in angular through multiples examples.
Table of Contents
What is RxJs map() operator in angular ?
As we know, Angular is providing a powerful library called RxJS (can be used separately),
this tool is providing multiples operators that help us to map the data stream to whatever format we need.
RxJs comes with a basic function of mapping called map(), and it’s the most used operator by the developers when they need to do some basic manipulation of the data stream.
The map operator applies a given function that can modify the data to each value emitted by the source and emit the result as a new observable.
As we know, we can use the map function to manipulate the data of an array too (array.map(myFunction)) , the difference here is that when we map an array we will get only the value of the current index , meanwhile when we use the RxJs map() operator in angular we will get an observable that means we can do more additional operations easily.
How the RxJS map() operator apply the modification ?
the following image explains how the map() operator apply the modification to every value in the pipeline.
Image Source : RxJs.Dev
RxJS Map() operator Syntax :
map
(project: (value: T, index: number) => R, thisArg?: any): OperatorFunction
Source : RxJs.Dev
how to use RxJS map() operator in angular ?
like any other angular library, the RxJS map() operator need to be imported in our project.
import { map } from ‘rxjs/operators’
Now we need to build our source observable, we will use in our example a magic operator called From(), we can use Of() too.
The operator of() and From() allows us to create a new observable from and input ( Object , Array , … ).
ArrayOfNumbers$ = from([1, 2, 3, 4 , 5 , 6 ,7 , 8, 9, 10]);
Note that starting from the version 6 of RxJS , the map operator has been removed, that mean we need to use pipe() operator to use the map().
Now, let’s put all together and see the result.
multiplyBy10() : void {
this.ArrayOfNumbers$
.pipe(map((value : number )=> { return val * 10}))
.subscribe((val : number ) => { console.log(val)})
}
When we subscribe, we get the response of our observable.
Now if we check the console log we will see something like this as output :
Output : 10 , 20 , 30 , 40, …., 100
The map() operator in angular accept a second parameter called the Index, and it is incremented for each new emitted value.
multiplyBy10() : void {
this.ArrayOfNumbers$
.pipe(map((value : number , index : number )=> { return val * 10}))
.subscribe((val : number ) => { console.log(val)})
}
use RxJS map() operator in real live example
Imagine that you are creating a simple drawing application, and you need to have the position of the mouse for every user click to save them and use all the clicked positions later to draw something.
RxJS library provide us multiples operators to do that easily.
First we can use an RxJS operator called fromEvent(), this operator creates an observable from any event (click , keyUp ,scroll ..).
Next, we use the RxJS map() operator to manipulate and extract the needed data from the emitted values of the source observable( click Event )
Finally, we subscribe and get the position of every mouse click.
import { fromEvent, map } from 'rxjs';
const clickedPositions = [];
const clicks$ = fromEvent(document, 'click');
clicks$.pipe(map(event => event.clientX))
.subscribe(position => {
// clickedPositions array will contain all clicked positions
// do whatever you want with that list
this.clickedPositions.push(position);
});
In this tutorial we have leaned when and how to use the RxJS map() operator in angular , also we have seen haw to use it with an RxJS observable$ in real life example.
I hope you enjoy reading this Tutorial.
Troubleshoot
Problem : Property ‘map’ does not exist on type ‘Observable’
Property ‘map’ does not exist on type ‘Observable’ (anywhere where I’ve used map with an observable)
c:/path/node_modules/rxjs/add/operator/map.d.ts(2,16): error TS2435: Ambient modules cannot be nested in other modules or namespaces.c:/path/node_modules/rxjs/add/operator/map.d.ts(2,16): error TS2436: Ambient module declaration cannot specify a relative module name.
Solution 1 : update your angular Cli and the core version and install rxjs-compat
ng update @angular/cli
ng update @angular/core
npm install --save rxjs-compat
Solution 2 : if you are using the latest version of RxJS then you need to use the pipe():
import { map } from “rxjs/operators”;
use your map() operator inside the pipe()
observable$.pipe(map(data => {}))
I hope you enjoy reading this Tutorial.