Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

do (tap) vs subscribe

Edit: Prior to RxJs 6, tap was called as do . Updated title to reflect tap too.

I would like to understand what is the best practice of using .subscribe and .do methods of Observables.

For example if I need to do some job after initial data is loaded from server

const init$: Observable<MyData> = this._dataService.getData();

init$
  .do((initialData: MyData) => {
    this.data = initialData; // at this step I am initializing the view
  })
  .switchMap(() => loadExtraData)
  .subscribe((extraData) => {
     doSomething(extraData, this._data); // I need this._data here
  }); 

I can do the same with .subscribe

const init$: Observable<MyData> = this._dataService.getData()
  .shareReplay(1);

init$
  .subscribe((initialData: MyData) => {
    this.data = initialData; // at this step I am initializing the view
  })

init$
  .combineLatest(loadExtraData)
  .subscribe(([initialData, extraData]) => {
     doSomething(extraData, initialData); // I need this._data here
  }); 

Which one is better and why?

like image 914
mgrinko Avatar asked Jul 26 '17 08:07

mgrinko


People also ask

What is the difference between pipe and subscribe?

The pipe method is for chaining observable operators, and the subscribe is for activating the observable and listening for emitted values. The pipe method was added to allow webpack to drop unused operators from the final JavaScript bundle. It makes it easier to build smaller files.

What can I use instead of subscribe?

Some common synonyms of subscribe are accede, acquiesce, agree, assent, and consent.

What is the difference between tap and map?

The map operator will simply apply a function to that data and return the result. The tap operator however takes a data, apply a function to that data but returns the original data, if the function bothered to return a result, tap just ignores it.

What does tap do in RxJS?

RxJS tap() operator is a utility operator that returns an observable output that is identical to the source observable but performs a side effect for every emission on the source observable.


1 Answers

Edit: For RxJS 6 or above, Read do as tap.

do is used for side-effects. subscribe is used to invoke an observable. Replacing do with subscribe creates undesired results. Replacing subscribe with do will not even invoke the stream.

Consider these examples :

Using subscribe :

const testObservable = Rx.Observable.create(function(observer){
   console.log('some heavy task, may be network call ');
   observer.next('success');
});

testObservable.subscribe(function(res){
    console.log('action 1');
});

testObservable.subscribe(function(res){
   console.log('action 2');
});

The output of the above code is

"some heavy task, may be network call "
"action 1"
"some heavy task, may be network call "
"action 2"

You can see the Rx.Observable.create got executed twice. Our goal is do it only once but along with action 2, do action 1 also.

Using do:

const testObservable = Rx.Observable.create(function(observer){
   console.log('some heavy task, may be network call ');
   observer.next('success');
});

testObservable
    .do(function(res){
        console.log('action 1');
    })  
    .subscribe(function(res){
        console.log('action 2');
    });

The output would be

"some heavy task, may be network call "
"action 1"
"action 2"

This is what we actually wanted. We need 'action 2' but before that do 'action 1' also.

Why is it called side effect:

Because it will not affect the flow of stream unlike other operators. It takes the response , does something and even if it modifies the response the stream is going to ignore it . For ex:

testObservable
    .do(function(res){
        console.log('action 1');
        return res+'some other text';
    })  
    .subscribe(function(res){
        console.log('action 1');
    });

The above code will still give the same output as before. So no matter what you execute in do the stream is going to ignore it and proceed with its execution.

If we are doing pure 'functional reactive programming' we don't want any side effects in the stream. So, do is discouraged and mostly used only for debugging purposes .

like image 123
Vamshi Avatar answered Oct 23 '22 12:10

Vamshi