Avraam Mavridis Avraam Mavridis - 1 month ago 7
Ajax Question

Start stream when another Observable emits its first value

I have two observables, one from key press events and another from ajax requests.
I want the second stream to start when the first stream emits its first value.

var input$ = Rx.Observable.fromEvent( input, 'keydown')
.debounceTime(500)


var countries$ = Rx.Observable.of('https://restcountries.eu/rest/v1/all')
.flatMap(url => $.get( url ))
.retryWhen( errors => {
return errors.scan( (sum, err) => {
if( sum === 2 )
{
throw err;
}
else{
return sum + 1;
}
}, 0).delay(1000)
})


I am using rxjs 5, I want the
countries$
observable to start when the
input$
observable emits its first value. I tried using
skipUntil
or
debounce
passing the
input$
Observable but... no luck. I see the ajax request happening in the network tab before I start typing anything. Any idea how I can achieve what I want?

Answer

Use switchMap. This will switch from the source stream to the new stream whenever the source Observable emits

var url = 'https://restcountries.eu/rest/v1/all';

var countries$ = input$.switchMap(input => $.get(url))
                       .retryWhen(...

Note that if a new input arrives before the http request is completed, the old request will be cancelled and a new one issued. So switchMap is perfect if the http request made depends on the specific input (as in a search query)

I used a static URL because that's what your OP uses, but you could easily alter the URL to include a query parameter built from the input.

If you wish to run the http request just once regardless of what the input was, and do not want to cancel the old request when a new input arrives, use take to only read from the source once:

var countries$ = input$.take(1).switchMap(input => $.get(url))
                       .retryWhen(...
Comments