Reputation: 65
I'm tring to get results from server, and retry until i get the right results using rxjs.
code snippet:
const intervalSub = interval(timeout).subscribe(t => {
const userSearchSub2 = this.userSearchService.getSearchResult(searchReq).subscribe(xx => {
if (xx.results) {
this.dataSource.data = xx.results.map((item: any) => item.values);
intervalSub.unsubscribe();
}
userSearchSub2.unsubscribe();
});
});
Since the inerval is faster than 'getSearchResult', getSearchResult executes several times even if i get my results in the first attempts.
wanted behavior:
Stop interval until i check the results of getSearchResult, so getSearchResult do not fire again if i have my results
Upvotes: 1
Views: 161
Reputation: 11979
This seems to be a good use case for exhaustMap.
You have an outer observable(the interval) and for each emitted value, you would want to make a request, which will create another observable(inner observable), but you do not want to go to the next emission of the interval until the current inner observable completes.
let resultsFound = false;
interval(timeout)
.pipe(
takeWhile(() => !resultsFound),
exhaustMap(() => this.userSearchService.getSearchResult(searchReq)),
map(xx => {
if (xx.results) {
resultsFound = true;
return xx.results.map((item: any) => item.values);
}
return null;
}),
filter(v => !!v),
)
.subscribe(results => console.log(results))
Your case is similar to http polling. Might be worth checking the provided link out.
When takeWhile
's predicate function returns false(() => !resultsFound
, resultsFound = true
), it will automatically unsubscribe from the outer observalbe.
Upvotes: 2