9

I'm writing a timer stream using Date.now() and I'm having a problem understanding a detail.

When I write the stream using a switchMap, it works fine, and the getTestStartTime$() is called after the start$ starts emitting events.

let start$ = Observable.fromEvent(document.querySelector('#start'), 'click');
let stop$ = Observable.fromEvent(document.querySelector('#stop'), 'click');

let getTestStartTime$ = () => Observable.of(Date.now())
    .delay(sampleTime)
    .repeat()
    .takeWhile(val => true);

let time$ = start$
    .switchMap(event => getTestStartTime$())
    .map(startTime => Date.now() - startTime)
    .map(diff => diff / 1000)
    .takeUntil(stop$)
    .repeat();

But when replacing switchMap with switchMapTo it seems the function is called before the start$ is firing. I can see this because Date.now() is called too early (it has the same time as the time of pageload).

let time$ = start$
    .switchMapTo(getTestStartTime$()) // this calls getTestStartTime$ too early
    .map(startTime => Date.now() - startTime)
    .map(diff => diff / 1000)
    .takeUntil(stop$)
    .repeat();

Thanks.

skovmand
  • 4,372
  • 5
  • 25
  • 30
  • I found that writing .switchMap(getTestStartTime$) works as intended. Still don't get the difference btw .switchMap and .switchMapTo though. – skovmand Aug 23 '16 at 19:14

1 Answers1

43

It is calling early because you are calling the function when you are building the stream.

switchMap takes a function which gets invoked when a new value comes from up stream. The result of that function is subscribed to as a new stream.

switchMapTo takes an Observable which is subscribed to for every value that comes from up stream. You are creating the Observable by invoking getTestStartTime$().

Use switchMap when the output depends on the value coming from upstream, and use switchMapTo when the actual upstream value is irrelevant and is only used as a signal for subscription.

paulpdaniels
  • 18,395
  • 2
  • 51
  • 55