Reputation: 423
I need to create a polling operator using Rxjs, that does not use a time source (e.g. timer or interval). This will be used to poll a third party api that is wildly inconsistent with the amount of time it takes to return a value. I only want to poll again if the value returned is empty.
What I've tried so far is
this.someService.getStoredValue().pipe(
repeatWhen(newPoll => newPoll.pipe( // delay each resubmission by two seconds
delay(2000)
)),
pluck('Data), // only interested in the Data property of the returned object
filter(isNotNull => isNotNull !== ''),
timeout(20000), // if gone 20 seconds without a successfull polling attempt, throw error
).subscribe({
next: value => {
// Only if polling is succesfull
},
error: err => {
// I want to end up here if the api can not be reached, or the timeout occurs.
},
complete: () => console.log('completed')
})
I expect the output of the operator to try polling, for instance 10 times. If the Data property of the returned object has a non-empty value, unsubscribe from the polling service. If 10 attempts has been made, unsubscribe and emit an error.
But what happens is that the subscription goes on for infinity if the polling is never successful.
Upvotes: 0
Views: 363
Reputation: 3263
I would definitely recommend the takeWhileInclusive operator, which can be downloaded here: https://www.npmjs.com/package/rxjs-take-while-inclusive
interval(1000).pipe(
takeWhileInclusive((data) => runCondition(data)))
.subscribe(console.log)
);
Just pass in your condition as a function and add your interval time and it will work.
Upvotes: 0
Reputation: 14689
It seems like a retry
case, with a catch that an empty answer should be treated as an error. Something like:
this.someService.getStoredValue().pipe(
pluck('Data'),
flatMap(value => !!value ? of(value) : throwError("Empty!")),
retry(10),
)
Upvotes: 2