Reputation: 693
New to Angular and RxJS, trying to understand this a bit... my app reacts to a UI event and that results in making a call out to a HTTP service that returns an Observable. I subscribe to it like so:
this.myXYZService.search(query)
.map(r => { // some code })
.subscribe(r => { //some code });
Say that event triggers again and it results in making a second call out to the same HTTP service that will return a brand new Observable BEFORE the 1st call finishes.
Now, as I understand it I can use switchMap instead of map to discard the old Observable and operate on the new Observable? Or am I understanding this incorrectly? And what happens if the second event triggers after the 1st event is already in the subscribe part of the chain? In this case it will no longer switch? And since JS is synchronous wouldn't the entire 1st chain execute anyway before the 2nd event even starts processing its chain?
I guess I am confused by the whole thing because the instances of the Observables are different - how does Rx keep track which call to switch?? Is it by the function name? Say I have 2 separate blocks of code:
this.myXYZService.search('abcd')
.map(r => { // some code })
.subscribe(r => { //some code });
this.myXYZService.search('efgh')
.map(r => { // some code })
.subscribe(r => { //some code });
if I use switchMap on both of the above what exactly happens? Does the second call cancel out the first?
Upvotes: 2
Views: 5564
Reputation: 13396
switchMap cancels the previous inner observable when the outer observable emits. For example
Observable.fromEvent(inputEl, 'keydown') // outer observable
.switchMap(event => {
let value = event.value;
return this.myXYZService.search(value); // inner observable
})
.subscribe(res => {
// some code
});
In this case, every time the outer observable (fromEvent) emits (on keydown of input element), the inner observable (myXYZService.search) is called and the previous inner observable is cancelled.
Upvotes: 10
Reputation: 43797
You would want something like...
searchTerms.switchMap(
searchTerm => this.myXYZService.search(searchTerm)
).subscribe(...)
As soon as a new search term arrives then any in-progress search calls will be ignored / discarded. I wouldn't use the word cancelled because the call still goes out. However, their result will be ignored.
If the first request returns before the second search term is emitted then it will be sent to the subscription. If it doesn't then it will not.
Upvotes: 3