I'm building a simple stopwatch with angular/rxjs6, I can start the timer but I can't pause/resume it.
source: Observable<number>;
subscribe: Subscription;
start() {
this.source = timer(0, 1000);
this.subscribe = this.source
.subscribe(number => {
this.toSeconds = number % 60;
this.toMinutes = Math.floor(number / 60);
this.toHours = Math.floor(number / (60 * 60));
this.seconds = (this.toSeconds < 10 ? '0' : '') + this.toSeconds;
this.minutes = (this.toMinutes < 10 ? '0' : '') + this.toMinutes;
this.hours = (this.toHours < 10 ? '0' : '') + this.toHours;
});
}
pause() {
this.subscribe.unsubscribe(); // not working
}
after doing lot of searching, I found that I should use switchMap
operator to accomplish that, but I'm new to rxjs and don't know how to do it the right way.
Any help would be much appreciated.
The custom observable creates a stream that outputs the number on the stopwatch and is controlled by a separate stream (Here called control$ ). When control$ emits "START", the stopWatch starts, when it emits "STOP", the stopwatch stops, and when it emits "RESET" the stopwatch sets the counter back to zero.
Creates an observable that will wait for a specified time period, or exact date, before emitting the number 0.
I've faced the same problem today (when implementing Tetris clone with Angular). Here is what I ended up with:
import { Subject, timer } from 'rxjs';
export class Timer {
private timeElapsed = 0;
private timer = null;
private subscription = null;
private readonly step: number;
update = new Subject<number>();
constructor(step: number) {
this.timeElapsed = 0;
this.step = step;
}
start() {
this.timer = timer(this.step, this.step);
this.subscription = this.timer.subscribe(() => {
this.timeElapsed = this.timeElapsed + this.step;
this.update.next(this.timeElapsed);
});
}
pause() {
if (this.timer) {
this.subscription.unsubscribe();
this.timer = null;
} else {
this.start();
}
}
stop() {
if (this.timer) {
this.subscription.unsubscribe();
this.timer = null;
}
}
}
And in my game service I use it like this:
init() {
this.timer = new Timer(50);
this.timer.start();
this.timer.update.subscribe(timeElapsed => {
if (timeElapsed % 1000 === 0) {
this.step(); // step() runs one game iteration
}
});
}
togglePause() {
this.timer.pause();
}
N.B.: I'm new to Angular/RxJS, so I'm not sure if the code above is good. But it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With