Top 9 commonly used rxjs operators in angular

 


Rxjs Operators are special type of functions that take input as an observable and then return an observable as an output that means Operators work with observable to make various kind of operations in angular or JavaScript. Operators may help us make Angular application more faster

Today I am going to share top 9 commonly used Rxjs operators you need to know to get started with. In the Queue first we have 

1. map Operator

map() Operator is most commonly used operator while using Rxjs. it is used to to transform the each value emitted by the source observable. simply it creates new observable after manipulating the each items of source observable.
 
We use map() operator in pipe function where we can chain multiple operator together to get the desired output from an observable. Lets see how we can apply projection with each value from source observable.

// RxJS v6+
import { from } from 'rxjs';
import { map } from 'rxjs/operators';

//emit (1,2,3,4,5)
const source = from([1, 2, 3, 4, 5]);
//add 10 to each value
const example = source.pipe(map(val => val + 10));
//output: 11,12,13,14,15
const subscribe = example.subscribe(val => console.log(val));

2. debounceTime Operator 

While working on web page we often have such scenarios where we have to control user input or typing. there we get debounceTime() on the track. with the help of debounceTime() we can create delay for given time span and without another source emission. 

The best part of debounceTime() is that within the given time span if a new value arrives then the previous pending value gets dropped so we only get the latest value emitted by the source observable.

// RxJS v6+
import { fromEvent } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';

// elem ref
const searchBox = document.getElementById('search');

// streams
const keyup$ = fromEvent(searchBox, 'keyup');

// wait .5s between keyups to emit current value
keyup$
  .pipe(
    map((i: any) => i.currentTarget.value),
    debounceTime(500)
  )
  .subscribe(console.log);

3. distinctUnitChanged Operator 

In such scenario where we get input from user and want to avoid unnecessary API hits e.g. Search box. Where we only want distinct values based on last emitted value to hit the API. 
then distinctUntilChanged operators comes in the game and handle such scenarios so that application can avoid unnecessary API hit.

 With this operator we can use debounceTime() to give it some time to get the distinct value for search bar kind's of functionalities. debounceTime() and distinctUnitChanged() makes search bar more productive. These both operators return an observable.

// RxJS v6+
import { from } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

// only output distinct values, based on the last emitted value
const source$ = from([1, 1, 2, 2, 3, 3]);

source$
  .pipe(distinctUntilChanged())
  // output: 1,2,3
  .subscribe(console.log);

4. throttleTime operator 

Throttle time can make a delay given to it but first emits value from source observable and it  is used to ignore subscription for given time like when we want to hit an API but you want a delay but want to get the latest value emitted from source observable then,

ThrottleTime can be used. it seems similar to debounceTime where it is also make delay for the subscriptions but debounceTime() is only emits the last value emitted in source observable and throttleTime() picks the latest value emitted in the source observable.

// RxJS v6+
import { interval } from 'rxjs';
import { throttleTime } from 'rxjs/operators';

// emit value every 1 second
const source = interval(1000);
/*
  emit the first value, then ignore for 5 seconds. repeat...
*/
const example = source.pipe(throttleTime(5000));
// output: 0...6...12
const subscribe = example.subscribe(val => console.log(val));

5. forkJoin Operator 

We can use multiple observable execution with forkJoin() operator but it waits for all observables to be completed then it only emits the last value from each observable Remember if any of the observable does not complete then the forkJoin() will never complete.

This operator is best when you have such scenarios where you want to get the only last value while having group of observable execution. this is not a best choice to used for multiple API calls because there if we have error in any of the API's then if the error is not handle properly it might get you in trouble so it is not considered as a best approach,

On that place you can use combineLatest and zip operator but if you are not making API hit with forkJoin() for multiple observable executions then forkJoin() is best approach.

// RxJS v6.5+
import { ajax } from 'rxjs/ajax';
import { forkJoin } from 'rxjs';

/*
  when all observables complete, provide the last
  emitted value from each as dictionary
*/
forkJoin(
  // as of RxJS 6.5+ we can use a dictionary of sources
  {
    google: ajax.getJSON('https://api.github.com/users/google'),
    microsoft: ajax.getJSON('https://api.github.com/users/microsoft'),
    users: ajax.getJSON('https://api.github.com/users')
  }
)
  // { google: object, microsoft: object, users: array }
  .subscribe(console.log);

6. pluck operator 

Pluck operator is used to pluck a property or value and then return in subscription. pluck is useful when you don't want unnecessary in the stream and you can pluck them in the on going execution. pluck will return undefined if it does not find the given property of value in it.

We can pluck multiple property like if we use an observable of array type then we can select multiple properties to be plucked.

// RxJS v6+
import { from } from 'rxjs';
import { pluck } from 'rxjs/operators';

const source = from([
  { name: 'Joe', age: 30, job: { title: 'Developer', language: 'JavaScript' } },
  //will return undefined when no job is found
  { name: 'Sarah', age: 35 }
]);
//grab title property under job
const example = source.pipe(pluck('job', 'title'));
//output: "Developer" , undefined
const subscribe = example.subscribe(val => console.log(val));

7. catchError() operator 

catchError is used to handle errors when we have sequence of source observables. this operator take cares to return error or new observable in case of catching errors on the source observable

If is a pipeable operator so it can be used in pipe function in an observable. this function takes an argument then return an observable instance.

import { of } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

of(1, 2, 3, 4, 5).pipe(
    map(n => {
  	   if (n === 4) {
	       throw 'four!';
      }
     return n;
    }),
    catchError(err => of('I', 'II', 'III', 'IV', 'V')),
  )
  .subscribe(x => console.log(x));
  // 1, 2, 3, I, II, III, IV, V

8. mergeMap() operator 

Merge map is often get used when the requirement is to merge response from two observables. This operator return an observable after merging the response from two observables, things to notice here is that second observable does not execute until merged observable emits some response.
This is very popular operator of Rxjs we usually get to merge two responses of observable type while working with web pages in Angular or JavaScript.

import { of, interval } from 'rxjs';
import { mergeMap, map } from 'rxjs/operators';

const letters = of('a', 'b', 'c');
const result = letters.pipe(
  mergeMap(x => interval(1000).pipe(map(i => x+i))),
);
result.subscribe(x => console.log(x));

// Results in the following:
// a0
// b0
// c0
// a1
// b1
// c1
// continues to list a,b,c with respective ascending integers

9. combine latest operator 

Combine latest operator is used to execute multiple observable at once , it only emits the latest value from each source observable (does not like forkJoin() operator). 

To run combine latest operator we must have value in observable and combine latest will not execute until each of source observable emits at least one value.

// RxJS v6+
import { timer, combineLatest } from 'rxjs';

// timerOne emits first value at 1s, then once every 4s
const timerOne$ = timer(1000, 4000);
// timerTwo emits first value at 2s, then once every 4s
const timerTwo$ = timer(2000, 4000);
// timerThree emits first value at 3s, then once every 4s
const timerThree$ = timer(3000, 4000);

// when one timer emits, emit the latest values from each timer as an array
combineLatest(timerOne$, timerTwo$, timerThree$).subscribe(
  ([timerValOne, timerValTwo, timerValThree]) => {
    /*
      Example:
    timerThree first tick: 'Timer One Latest: 0, Timer Two Latest: 0, Timer Three Latest: 0
    timerOne second tick: 'Timer One Latest: 1, Timer Two Latest: 0, Timer Three Latest: 0
    timerTwo second tick: 'Timer One Latest: 1, Timer Two Latest: 1, Timer Three Latest: 0
  */
    console.log(
      `Timer One Latest: ${timerValOne},
     Timer Two Latest: ${timerValTwo},
     Timer Three Latest: ${timerValThree}`
    );
  }
);

Summary

In this Section, we focused on some of most commonly used rxjs Operators in Angular. The list is huge for Rxjs Operators check this link to find them all.
Thanks for reading. 

No comments:

Powered by Blogger.