snso
snso

Reputation: 329

How to cancel inner observable timer using rxjs?

I am trying to make a simple counter with Observable timer. Outside time runs every 5 seconds. And inner timer runs every one second because I would like to output something like the following:

Loading.. 5

Loading.. 4

Loading.. 3

...

But my problem is the inner observable does not cancel. It continues infinitely. What is the correct way of doing this?

Observable.timer(0, 5000)
  .pipe(
    tap(() => {
      Observable.timer(0, 1000)
        .subscribe(t => console.log(5 - t));
    }),
    tap(t => {
      this.count = this.users.length;
    }),
  ).subscribe();

Solution

Use switchMap operator to cancel outer observable

Observable.timer(0, 5000)
  .pipe(
    switchMap(() => {
      return Observable.timer(0, 1000);
    }),
    tap(t => {
      console.log(`%c`, 'background:red', 5 - (t));
      this.count = this.users.length;
    }),
  ).subscribe();

Upvotes: 0

Views: 320

Answers (1)

alex kucksdorf
alex kucksdorf

Reputation: 2633

I think what you are looking for is the take operator, see [http://reactivex.io/documentation/operators/take.html](the docs) for further explanation. You can use take(5) or take(6), depending if you want to count down to 0 or 1.

Observable.timer(0, 5000)
  .pipe(
    tap(() => {
      Observable.timer(0, 1000)
        .take(5)
        .subscribe(t => console.log(5 - t));
    }),
    tap(t => {
      this.count = this.users.length;
    }),
  ).subscribe();

Upvotes: 1

Related Questions