Reputation: 5968
One of my Observable.combineLatest
never completes because one of its observables never gets to emit a value, so the completion function is never reached.
Is there a way so I can set a kind of a timeOut
so after it I can provide a default value for it? or at least a way to tell which observable is not emiting any data at all?
Something like
Observable.combineLatest(...).onTimeOut(() => console.log('No data from 3th observable')
Edit:
So given this:
Observable.combineLatest(
observable1, // <- ok
observable2, // <- ok
observable3, // <- timeout
observable4, // <- ok
observable5, // <- ok
(...args) => ({...args})
)
.pipe(
timeout(1*1000),
catchError((e) => {
console.log(e)
return Observable.of({})
})
)
.subscribe(() => {})
How can I tell that observable3 was the responsible of the timeout?
Upvotes: 1
Views: 1104
Reputation: 6986
You can use the timeout and catchError operator (or just timeoutWith, see edit below) for this use case:
combineLatest(...).pipe(
timeout(myTimeoutValueInMilliseconds),
// Catch the error thrown by the timeout and return a default value instead.
catchError(() => of('my default value'))
).subscribe(e => console.log(e))
Of course if you need the timeout on only one of the Observables then you can restructure it as follows:
combineLatest(
myObsOne.pipe(
timeout(myTimeoutValueInMilliseconds),
catchError(() => of('my default value'))
),
myObsTwo
).subscribe(e => console.log(e))
As pointed out by Oles Savluk in the comments, you can simplify this solution by using timoutWith instead of timeout
and catchError
:
combineLatest(
myObsOne.pipe(
timeoutWith(myTimeoutValueInMilliseconds, of('my default value')),
),
myObsTwo
).subscribe(e => console.log(e))
Upvotes: 1