Reputation:
This is not related to a bug I am encountering, but rather a syntax issue.
The workflow is simple :
To manage that, my current code is this :
Boilerplate
private _getBoolean() { return this.http.get(...); }
private _getData() { return this.http.get(...); }
Current code
public getData() {
return this._getBoolean().pipe(
filter(bool => {
if(!bool) {
console.warn('Wrong server answer, stream stopped');
return false;
}
return true;
}),
switchMap(bool => this._getData())
);
}
And I don't know why, but it doesn't feel natural and optimized to me.
I thought that there would be something that simplifies the syntax, something like this
public getData() {
return this._getBoolean().pipe(
throwError(bool => bool ? new Error('Wrong server answer, stream stopped') : null),
catchError(err => console.warn(err)),
switchMap(bool => this._getData())
);
}
Is there something along the lines of that, or do I have the correct syntax ?
Upvotes: 1
Views: 5064
Reputation: 15191
instead of:
public getData() {
return this._getBoolean().pipe(
throwError(bool => bool ? new Error('Wrong server answer, stream stopped') : null),
catchError(err => console.warn(err)),
switchMap(bool => this._getData())
);
}
why not something like:
public getData() {
return this._getBoolean().pipe(
tap(result => !result && throwError('Wrong server answer, stream stopped')),
switchMap(bool => this._getData()),
catchError(err => console.warn(err))
);
}
Upvotes: 1
Reputation: 6966
Consider the following observable below that emits value 1 to 4. Let's say an error is thrown when the value is 3. That error can be caught in the catchError
operator or it can be caught within the subscribe
. I believe it depends on the specific use case whether you let the error bubble all the way up to the subscriber or whether it should be handled somewhere upstream of the subscriber.
of(1, 2, 3, 4).pipe(
// Throw error when value is 3
tap(value => { if(value === 3) throw new Error('Oops!') }),
catchError(err => {
console.log('Catch error in operator', err);
// You can rethrow the same error or a new error
// return throwError(err);
// Or you can handle the error and return a new observable
return of(3)
})
).subscribe(
value => console.log(value),
// If `catchError` returns a new observable, then the error
// function here will not be called
err => console.log('Catch error within subscribe', err),
() => console.log('Done!')
)
Note that in this example, even if the error is being handled the observable completes and the value 4 is never emitted. If you wish to keep the observable alive when en error is encountered then have a look at this StackOverflow answer.
Upvotes: 1
Reputation: 3436
I'm not sure if I get your issue correctly, but you might replace
console.warn('Wrong server answer, stream stopped');
return false;
With
Observable.throw('Some error cause')
And then catch it with nearest catch
block in your stream, which gives you basically change to:
- Stop stream if you re-throw error
- Restart it if you return input observable
- return completely new observable
public getData() {
return this._getBoolean().pipe(
filter(bool => {
if(!bool) {
console.warn('Wrong server answer, stream stopped');
//return false;
Observable.throw('I got false where I expected true')
}
return true;
}),
switchMap(bool => this._getData())
);
}
And then:
getData()
.any()
.operator()
.you()
.wish()
.catch(e => {
/* Here stream will be terminated on thrown error */
})
Upvotes: 0