José Carballosa
José Carballosa

Reputation: 81

Why is this tap operator not firing?

I'm puzzled by this rxjs tap() operator never firing in this simple Angular component, while the Subject value does get updated on the screen. I also tried using a BehaviorSubject instead with the same results. What I'm I doing wrong here?

import { Component } from '@angular/core';

import { Subject, BehaviorSubject } from 'rxjs';
import { tap } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  template: '{{ selectedUserId | async }}',
})
export class AppComponent { 

  selectedUserId = new Subject<number>();
  // selectedUserId = new BehaviorSubject<number>(0);

  ngOnInit() {
    this.selectedUserId
      .pipe(
        tap(id => console.log(id)) // why this is not logging to console?
      );
    setTimeout(() => this.selectedUserId.next(1), 1000);
    //this.selectedUserId.next(1);
  }

}

Upvotes: 3

Views: 2887

Answers (2)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

this line 👉 this.selectedUserId.pipe(tap(id => console.log(id)) ); return an new observable base of selectedUserId so you need to subscribe to new observable the start get the values and .

tab operater will work on the new observable and not effected the base observable (selectedUserId)

  const obs =  this.selectedUserId
      .pipe(
        tap(id => console.log(id)) 
      );

   obs.subscribe()

demo 🔥🔥

to make it clear the new observable will be run by async pipe , not that the values of observable will change base of the subject observable during the time

  private selectedUserId = new Subject<number>();
  public userId$ : Observable<number>;

  ngOnInit() {
   this.userId$ =  this.selectedUserId
      .pipe(
        tap(id => console.log(id)) ,
      );

    setTimeout(() => this.selectedUserId.next(1), 1000);
    setTimeout(() => this.selectedUserId.next(2), 2500);
    setTimeout(() => this.selectedUserId.next(3), 5000);
  }

template

{{ userId$ | async }}

demo 🚀🚀

Upvotes: 1

meriton
meriton

Reputation: 70564

That's because the Observable the async pipe subscribes to doesn't have a tap.

Specifically, the pipe operator in

this.selectedUserId
  .pipe(
    tap(id => console.log(id)) // why this is not logging to console?
  );

doesn't modify the Observable stored in this.selectedUserId. Rather, it creates and returns a new Observable with the tap, but since you never subscribe to the returned Observable the tap is never called ...

Upvotes: 3

Related Questions