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'));