I recently asked a question related to subscriptions being lost if switchMap encountered an error:
Angular 4 losing subscription with router paramMap using switchMap
The solution was to return an empty Observable as once an Observable hits an error the subscription will be destroyed.
I now need to figure out how to poll with the same code but stop polling once the API returns data - I believe returning this empty Observable is causing my polling code to not work as expected.
Current code WITHOUT POLLING:
ngOnInit() {
this.subscription = this.route.paramMap
.switchMap( (params) => {
this.setChartDefaults();
return this.getForecastData(params.get('id'))
.do(null, (err) => {
this.errorText = err.statusText
this.loading = false;
})
.catch( () => { return Observable.empty() });
})
}
ngAfterViewInit() {
this.subscription.subscribe( (data) => {
// business logic
}
}
Proposed code WITH POLLING:
ngOnInit() {
this.subscription = this.route.paramMap
.switchMap( (params) => {
return Observable
.interval(10000)
.startWith(0)
.flatMap( () => {
return this.getForecastData(params.get('id'))
})
.filter( (val) => {
return val.Interval != null
})
.take(1)
.map((forecast) => forecast)
.do(null, (err) => {
this.errorText = err.statusText
this.loading = false;
})
.catch( () => { return Observable.empty() });
})
}
ngAfterViewInit() {
this.subscription.subscribe( (data) => {
// business logic
}
}
- switchMap on route.paramMap, meaning any previous Observables are cancelled
- return new Observable that has interval of 10 seconds and starts immediately
- flatMap the HTTP request and polling Observables
- filter the incoming data, if it has a property of Interval then take it and stop polling
- map returns a new observable thats needed for the subscribe
- the catch is there returning an empty observable to handle the original issue
This code is always taking the first result (with the use of take(1)) however it was my understanding that if you filter first you can pragmatically only take the first result that is valid (in my case has a valid response).
This is my current, limited understanding and believe there are clearly gaps in my knowledge so I'm attempting to learn more about how chaining of these operators and Observables works.
take(1)
so theObservable.interval
emits always only one item and then the chain is complete. – martin