Issue
I need a timeout
operator to throw an error when parameter isTimeoutNeeded
is True, so that I could handle the case if the subscribed observable do not emit any value after X seconds.
if (isTimeoutNeeded) {
this.service.getData()
.pipe(
timeout(10000),
...
)
.subscribe((...) => ...);
} else {
this.service.getData()
.pipe(
...
)
.subscribe((...) => ...);
}
Is it possible to write this in a rxjs way by conditionally adding timeout
operator when needed?
I have tried using iif
and switchMap
but it did not work.
this.service.getData()
.pipe(
mergeMap((response) =>
iif(() => !isTimeoutNeeded,
of(response),
of(response).pipe(timeout(10000)) // did not apply timeout if isTimeoutNeeded = True
)
)
.subscribe((...) => ...);
switchMap
this.service.getData()
.pipe(
switchMap((response) => {
if (!isTimeoutNeeded) {
return of(response);
}
return of(response).timeout(10000); // did not apply timeout if isTimeoutNeeded = True
})
.....
)
)
.subscribe((...) => ...);
Solution
RXJS works best when the operators easily describe the behavior without detailing the implementation. When you start using switchMap()
and conditions to express a behavior the intent gets lost, and the code becomes difficult to maintain.
So just write your own operator.
function timeoutWhen<T>(cond: boolean, value: number): OperatorFunction<T, T> {
return function(source: Observable<T>): Observable<T> {
return cond ? source.pipe(timeout(value)) : source;
}
}
Now when you use that operator the source code is easy to read and understand.
this.service.getData().pipe(
timeoutWhen(isTimeoutNeeded, 10000),
...
).subscribe((...) => ...);
Now you have something that is reusable and makes your observables easier to read and understand.
Answered By - Reactgular
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.