Imagine a simple task: There is a button on the page, and when you click the button, you need to start a timer. Using RxJS we can easily achieve the above functions:

While the above code works, there are two problems:

There is a problem similar to the location of the callback. We had to handle each subscription manually.

Let’s take a look at higher-order Observables and how they can be used to make things easier. Higher-order Observables

An Observable object can emit any type of value: numeric values, strings, objects, and so on. This means that an Observable object can also emit values of type Observable.

Similar to higher-order functions in JavaScript, a higher-order Observable means that an Observable object internally returns another Observable object. At this point, let’s update the above example to get a more intuitive understanding of the above concepts:

import { fromEvent, interval } from ‘rxjs’;

import { map } from ‘rxjs/operators’;

const button = document.querySelector(‘button’);

const click$ = fromEvent(button, ‘click’);

const interval$ = interval(1000);

const clicksToInterval$ = click$.pipe(map(event => {

return interval$;

}));

clicksToInterval$.subscribe(intervalObservable =>

console.log(intervalObservable)

);

When the user clicks the button, our map operator returns an Interval Observable object. When we subscribe to the ClickStoInterval $object, we emit an IntervalObservable object.

When you subscribe to a ClickStoInterval $object, the console outputs an IntervalObservable object. The important thing to remember here is that Observable objects are lazy. To get a value from an Observable, you must perform a subscription operation, such as:

clicksToInterval$.subscribe(intervalObservable => {

intervalObservable.subscribe(num => {

 console.log(num);

});

});

After introducing the concept of higher-order Observable objects, let’s introduce two useful operators that can help us solve the problem mentioned above. mergeAll

When the inner observable emits, let me know by merging the value to the outer observable.

The mergeAll() operator does the same thing at the bottom as in the previous example: it takes an inner Observable object, performs a subscription, and then pushes the value to an observer object.

import { fromEvent, interval } from ‘rxjs’;

import { map, mergeAll } from ‘rxjs/operators’;

const click$ = fromEvent(button, ‘click’);

const interval$ = interval(1000);

const observable$ = click$.pipe(map(event => {

return interval$;

}));

observable$.mergeAll().subscribe(num => console.log(num));

In our example above, the source object is an Observable and the inner object is an Interval $Observable.

This is a general pattern in RxJS, so there is a shortcut to implement the same behavior — mergeMap() :

mergeMap() <=> map() + mergeAll()

const button = document.querySelector(‘button’);

const click$ = fromEvent(button, ‘click’);

const interval$ = interval(1000);

const observable$ = click$.pipe(mergeMap(event => {

return interval$;

}));

observable$.subscribe(num => console.log(num));

In the above code, whenever we click the button, we call the subscribe() method of the interval$object, which results in multiple separate timers in our page. If that’s what you want to do, that’s fine. But if you want to keep only one data source, you’ll need to use the switch() operator. switch

Like mergeMap() but when the source observable emits cancel any previous subscriptions of the inner observable.

Switch () is used to cancel the previous subscription and switch to the new one. If we update the code to the switch() operator, when we click the button several times, we can see that each time we click the button, we will get a new interval and the previous interval will be cancelled automatically.

const button = document.querySelector(‘button’);

const click$ = fromEvent(button, ‘click’);

const interval$ = interval(1000);

const observable$ = click$.pipe(

map(event => {

return interval$;

}),

switchAll()

);

observable$.subscribe(num => console.log(num));

As you can see, after clicking the button three times, we only have an Interval object. Instead, with the merge() operator, we have three separate Interval objects. When the source emits a new value, the switch operator unsubscribes to the previous internal subscription object.

This is also a common pattern in RxJS, so there is also a shortcut to implement the same behavior — switchMap() :

switchMap() <=> map() + switch()

const button = document.querySelector(‘button’);

const click$ = fromEvent(button, ‘click’);

const interval$ = interval(1000);

const observable$ = click$.pipe(

switchMap(event => {

return interval$;

}));

observable$.subscribe(num => console.log(num));

This article by the blog multiple platform
OpenWriteRelease!