Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

switchMapTo creates observable before subscription

Tags:

rxjs

rxjs5

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.

like image 686
skovmand Avatar asked Aug 23 '16 18:08

skovmand


1 Answers

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.

like image 190
paulpdaniels Avatar answered Nov 09 '22 00:11

paulpdaniels