DevFromEarth
DevFromEarth

Reputation: 39

Reset Observable.timer()

I've try to make my Timer but , have got one problem I couldn't understand how to reset(refresh) my timer.

startTimer() {
Observable.timer(this.countDownDuration, 1000)
        .map(i => this.countDownDuration - i)
        .take(this.countDownDuration + 1)
        .subscribe(i => {
          this.countDown = i;
          console.log(this.countDown);
        });
}

resetTimer() {
  must stop previous timer and start new 
}

Any suggestions

Upvotes: 0

Views: 1926

Answers (4)

David Bulté
David Bulté

Reputation: 3109

Here's another solution:

  recording$ = new BehaviorSubject(false);
  stopWatch$: Observable<number>;

  ngOnInit() {

    this.stopWatch$ = this.recording$.pipe(
      switchMap(r => r ? timer(0, 10) : never()),
      share()
    );

  }

  start() {
    this.recording$.next(true);
  }

  stop() {
    this.recording$.next(false);
  }

Upvotes: 0

m1ch4ls
m1ch4ls

Reputation: 3435

The martin's answer (https://stackoverflow.com/a/51726532/3024975) is correct, but I don't like subscribing the BehaviorSubject. So this is an alternative:

We need a way to sinal the Observable to restart itself. This is a good use case for Subject

const signal = new Subject();

Observable.defer(() => Observable.timer(this.countDownDuration, 1000))
  .takeUntil(signal)
  .repeat()
  .map(....)
  .subscribe(...);

resetTimer() {
  signal.next();
}

I use takeUntil to stop the Observable and immediately repeat it using repeat. defer is used to create timer with new this.countDownDuration value (I expect it's going to change).

Upvotes: 0

DevFromEarth
DevFromEarth

Reputation: 39

I found some another way for this. And in my example I must use take. I know how to reset throw switchMap. But it's not good for me. May be it'is not good decision.

status;

startTimer() {
this.status = Observable.timer(this.countDownDuration, 1000)
        .map(i => this.countDownDuration - i)
        .take(this.countDownDuration + 1)
        .subscribe(i => {
          this.countDown = i;
          console.log(this.countDown);
        });
}

resetTimer() {
  this.status.unsubscribe(); 
  this.startTimer();
}

Upvotes: 0

martin
martin

Reputation: 96969

const s = new BehaviorSubject(null);

s.switchMap(() => Observable.timer(this.countDownDuration, 1000))
  .map(...)
  ...
  .subscribe(...);

resetTimer() {
  s.next();
}

Upvotes: 2

Related Questions