RX.Observable.switchMap - countdown with restart
RxJS 5 switchMap
by David Gonzalez
HTML
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
<h4>
Time remaining: <span id="remaining"></span>
</h4>
<button id="pause">
Pause Timer
</button>
<button id="resume">
Resume Timer
</button>
<button id="restart">
Restart Timer
</button>
JavaScript
const countdownSeconds = 10;
const setHTML = id => val => document.getElementById(id).innerHTML = val;
const pauseButton = document.getElementById('pause');
const resumeButton = document.getElementById('resume');
const restartButton = document.getElementById('restart');
const interval$ = Rx.Observable.interval(1000).mapTo(-1);
const pause$ = Rx.Observable.fromEvent(pauseButton, 'click').mapTo({isPaused:true});
const resume$ = Rx.Observable.fromEvent(resumeButton, 'click').mapTo({isPaused:false});
const restart$ = Rx.Observable.fromEvent(restartButton, 'click').mapTo({isRestart:true});
Rx.Observable
.merge(pause$, resume$, restart$)
.startWith(interval$)
.switchMap(val => val.isRestart ? Rx.Observable.concat(Rx.Observable.of(countdownSeconds), interval$): val.isPaused? Rx.Observable.empty(): interval$)
.scan((acc, curr) => curr ? curr===countdownSeconds?countdownSeconds: acc? curr + acc : acc: 0, countdownSeconds)
//.takeWhile(v => v >= 0)
.subscribe(setHTML('remaining'));