Conditionally apply pipe operators
You were almost right using switchMap
:
const subject = new BehaviorSubject(this.service.getData());
subject
.pipe(
switchMap(response => {
// If isTimeoutNeeded, a timetout is applied else wait result forever.
return isTimeoutNeeded
? response.pipe(timeout(10000))
: response;
}),
...
)
.subscribe(... => ...);
In this code the timeout is applied on the getData
observable whereas in your example it was a new observable.
Check my Stackblitz example.
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.
For this particular case, I did it like this:
.pipe(
(isTimeoutNeeded? interval(5000) : identity)
)