angulartypescriptrxjssubscribetap

tap() vs subscribe() to set a class property


I am very new to rxjs and was just wondering is it ok to setup a class property by piping the stream and tapping it, or it should i do it in the subscribe. To me either way works, just wonder if it is ok to do it as I see fit to my eyes or there is something I am unaware of.

Typescript code demonstrating both ways:

export class ViewComponent implements OnInit {

  applicant = {};

  constructor(public route: ActivatedRoute, private store: Store<any>) {}

  ngOnInit() {
    this.route.paramMap.pipe(
      switchMap(params => this.store.select(state => state.applicants.entities[params.get('id')])),
      tap(applicant => this.applicant = applicant)
    ).subscribe();
  }
}

vs

export class ViewComponent implements OnInit {

  applicant = {};

  constructor(public route: ActivatedRoute, private store: Store<any>) {}

  ngOnInit() {
    this.route.paramMap.pipe(
      switchMap(params => this.store.select(state => state.applicants.entities[params.get('id')]))
    ).subscribe(applicant => this.applicant = applicant);
  }
}

Solution

  • tap is useful when you have the observable separated from its subscriber. If you have a class that exposes an observable, you can use tap to implement side effects that this class needs to be executed when someone is listening to the observable.

    On the other side, when you subscribe to it from another class, you can implement side effects from the subscriber's point of view, using subscribe.

    Class with the observable:

    public dummyObservable: Observable<number> = from([1, 2, 3, 4, 5]).pipe(
      // Side effects, executed every time I emit a value
      // I don't know which side effects implements who subscribes to me
      tap(n => console.log("I'm emitting this value:", n))
    );
    

    Class with the subscription:

    ngOnInit(): void {
      this.dummyService.dummyObservable.subscribe(
        // Side effects, executed every time I receive a value
        // I don't know which side effects implements the observable
        data => console.log("I'm receiving this value: ", data)
      );
    }