46

 Context :

I'm building an angular 2 app (with a Firebase API). I'm using the AngularFire module. I was wondering how I can mix the canActivate method with the AngularFire auth Observable, and I found this post. The answer is to make the canActivate method returns an Observable<boolean> :

canActivate(): Observable<boolean> {
  return this.auth
    .take(1)
    .map((authState: FirebaseAuthState) => !!authState)
    .do(authenticated => {
      if (!authenticated) this.router.navigate(['/login']);
    });
}

It's the first time I see the Observable do operator, and I can't understand what it really does ? The official doc didnt help me, and I didn't found decent examples.

Question:

Can someone bring here some examples of .do() usage ? And difference with .subscribe() ?

Community
  • 1
  • 1
soywod
  • 4,377
  • 3
  • 26
  • 47

2 Answers2

72

Update

Now it's pipe( tap(...), ) instead of do()

Original

.do() is to execute code for each event. A difference to .map() is, that the return value of .do() is ignored and doesn't change what value the subscriber receives.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 2
    OK I see, it's for doing some treatment without modify the stream. But I don't get why this work without a `subscribe` ? Does `do` do the same ? Can you give me some examples ? Thx for your reply anyway – soywod Dec 04 '16 at 10:12
  • 8
    @Soywod There is a subscribe: just not in your code. The router subscribes to the observable returned by your guard, to know if it can activate or not. – JB Nizet Dec 04 '16 at 10:21
  • So am I correct in saying that the side effect in the do() call will get executed after the router Subscriber function ? – codemonkey Aug 19 '17 at 18:48
  • 1
    @user2153465 `router.navigate` will be called when the observable returned by `this.auth` emits the first value. – Günter Zöchbauer Aug 19 '17 at 20:30
  • Can I use an observable wit do without sharing the observable? – Franki1986 May 29 '19 at 08:10
  • 1
    @Franki1986 sure, but you need to `subscribe()` otherwise the executable won't do anything and also not call `do(...)`. – Günter Zöchbauer May 29 '19 at 09:16
  • Hi @GünterZöchbauer. Is `do` operator still present in `RxJS`. I was going through the documentaion today and could not find it. If it is removed, is there any replacement for this operator. – Kiran Dash Sep 14 '19 at 15:37
  • It's `tap()` now – Günter Zöchbauer Sep 14 '19 at 15:58
8

Now it's pipe( tap(...), ) instead of do()

const source = of(1, 2, 3, 4);
source.pipe(
  tap(val => console.log('I am tap: ',val)),
  filter(val =>  val > 2),
  map(val => val + 1)).subscribe((val) => {
  console.log('I am subscriber value after filtering: ', val);
});

Output:

I am tap:  1
I am tap:  2
I am tap:  3
I am subscriber value after filtering:  4
I am tap:  4
I am subscriber value after filtering:  5

*Tap operator doesn't modify anything, you can say that it is just to view the stream.

Muhammad bin Yusrat
  • 1,433
  • 1
  • 14
  • 19
Muhammad Bilal
  • 1,840
  • 1
  • 18
  • 16