Wednesday, November 28, 2018

Switchmap

SwitchMap cancelled the previous inner subscription before subscribing the new.

Let’s say you have a simple task. You have a button, and when you click on it, you need to start an interval. Let’s see how we would implement this the simple way.

const button = document.querySelector('button');

Observable.fromEvent(button, 'click').subscribe(event => {

 Observable.interval(1000).subscribe(num => {
    console.log(num);
 });

});

We need to subscribe to the fromEvent() observable, which internally adds a new click event listener to our button. When the user clicks on the button, we need to subscribe to the interval() observable, which internally invokes the native JS setInterval() function.

When you click on button

0
1
2
3

While it works fine, there are two drawbacks to the code above.
1. It’s starting to look like callback hell.
2. We need to handle the disposal of every subscription by ourselves.

Let’s see how higher order observables make things easier for us.

A higher order observable is just a fancy name for an observable that emits observable. Let’s change the example a little bit so you can see what I’m talking about.


const click$ = Observable.fromEvent(button, 'click');
const interval$ = Observable.interval(1000);

const clicksToInterval$ = click$.map(event => {
  return interval$;
});

clicksToInterval$.subscribe(intervalObservable => console.log(intervalObservable));

When the user clicks on the button, we leverage the map() operator to return an interval() observable to the stream.

When we subscribe, the clicks$ observable will next() an interval observable.


the Output will be
IntervalObservable{}
IntervalObservable{}
IntervalObservable{}

You may notice that, in this case, we never invoke the interval. In contrast, in the first example, we saw the numbers running in the console.

That’s because we never called subscribe() on our interval$ observable. Remember that observables are lazy — if we want to pull a value out of an observable, we must subscribe().

clicksToInterval$.subscribe(intervalObservable$ => {

   intervalObservable$.subscribe(num => {
     console.log(num);
   });

});


mergeAll
When the inner observable emits, let me know by merging the value to the outer observable.
Under the hood, the mergeAll() operator basically does what we did in the last example. It takes the inner observable, subscribes to it, and pushes the value to the observer.

function myMergeMap(innerObservable) {

  /** the click observable, in our case */
  const source = this;

  return new Observable(observer => {
    source.subscribe(outerValue => {
 
      /** innerObservable — the interval observable, in our case */
      innerObservable(outerValue).subscribe(innerValue => {
        observer.next(innerValue);
      });
   
   });
  });
 }

 Observable.prototype.myMergeMap = myMergeMap;

From the above code, we can learn that each time we click on the button, we are invoking the subscribe() method of the inner interval() observable — which leads to multiple independent intervals in our page.

If this is what you’re after, you are good to go. But, if you want to cancel the previous subscriptions and keep only one, you’ll need the switch() operator.


switch
Like mergeMap() but when the source observable emits cancel any previous subscriptions of the inner observable.
As the name suggests, switch() switches to the new subscription and cancels the previous one.

If we change our code to switch() and click on the button multiple times, we’ll see that each time we click we are given a new interval and the previous one is canceled.



https://medium.com/@juliapassynkova/switchmap-in-details-b98d34145311

https://netbasal.com/understanding-mergemap-and-switchmap-in-rxjs-13cf9c57c885

No comments:

Followers

Link