'Custom Observable with setInterval with different polling duration
I am new to RxJS / Angular stuff and I am trying to implement a custom Observable for a polling kind of scenario.
Scenario:
From a button component in Angular typescript, I want to kickoff polling mechanism on a button click, get some data from an API, return the data back to the button component and based on the response I either want to call next(), complete() or error() on the button component where I actually do .subscribe().
Backend service API method myApi.service.ts
getSomeValue(input: string[]): Observable<MyModel[]> {
return this.httpClient.get<MyModel[]>(
`${<some-base-url>}/my-endpoint`,
);
}
Polling service polling.service.ts
startPolling(delayInMiliseconds: number): Observable<MyModel> {
this.myObservable$ = new Observable(observer => {
this.myInterval= setInterval(() => {
this.myApi.getSomeValue().subscribe(data => {
if (<some-condition>) {
observer.next(status);
}
else if (<some-condition>) {
observer.error();
}
else if (<some-condition>) {
observer.complete();
}
});
}, delayInMiliseconds);
})
return this.myObservable$;
}
button.component.ts
private onButtonClick(): void {
pollingService.startPolling(originalDelayInMiliseconds)
.subscribe(
(data) => {
if(data === something) {
console.log("This is the next poll / call to backend API");
let updatedDelayInMilisecondsInMiliseconds = recalculateDelayInMiliseconds();
// Do something so that polling continue with new updatedDelayInMilisecondsInMiliseconds
and I reset the interval defined in pollingService.
}
},
() => {
console.log("I errored out");
polllingService.stopInterval(); // This is working
},
() => {
console.log("I am completed");
polllingService.stopInterval(); // This is working
}
)
}
Problem
- When the backend service is called first time using observable, it calls with delay of
originalDelayInMiliseconds, this is correct and expected. - Now I want to call the same API via observable with the
updatedDelayInMilisecondsInMiliseconds. How can I call with the updated time, it gets called with the originalDelayInMiliseconds everytime - I will stop based on some condition but that is not the issue.
Things tried
- clearInterval in the next Handler in button component, so that it can take new miliseconds.
- calling the same pollingService.startPolling
- unsubscribe.
- repeatWhen in observable
Please help Any other suggestions??
Solution 1:[1]
class PollingService {
private pollingSubject = new Subject();
startPolling(initialDelay: number) {
this.pollAgain(initialDelay);
return this.pollingSubject.asObservable();
}
pollAgain(delay: number) {
setTimeout(() => {
this.pollingSubject.next();
}, delay);
}
stopPolling() {
this.pollingSubject.complete();
}
}
used like
pollingService.startPolling(originalDelayInMiliseconds)
.subscribe(
(data) => {
if(data === something) {
console.log("This is the next poll / call to backend API");
let updatedDelayInMilisecondsInMiliseconds = recalculateDelayInMiliseconds();
pollingService.pollAgain(updatedDelayInMilisecondsInMiliseconds)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Donald Duck |
