How do i execute the following scenario in the browser with RxJs:
We also have the same use case and the below code works pretty good.
import { timer, Observable } from "rxjs";
import { scan, tap, switchMapTo, first } from "rxjs/operators";
function checkAttempts(maxAttempts: number) {
return (attempts: number) => {
if (attempts > maxAttempts) {
throw new Error("Error: max attempts");
}
};
}
export function pollUntil(
pollInterval: number,
maxAttempts: number,
responsePredicate: (res: any) => boolean
) {
return (source$: Observable) =>
timer(0, pollInterval).pipe(
scan(attempts => ++attempts, 0),
tap(checkAttempts(maxAttempts)),
switchMapTo(source$),
first(responsePredicate)
);
}
if the number of attempts has reached the limit, an error is thrown which results in the output stream being unsubscribed. Moreover, you only make http requests until the given condition defined as responsePredicate is not met.
import { of } from "rxjs";
import { pollUntil } from "./poll-until-rxjs";
const responseObj = { body: { inProgress: true } };
const response$ = of(responseObj);
// this is to simulate a http call
response$
.pipe(pollUntil(1000, 3, ({ body }) => !body.inProgress))
.subscribe(({ body }) => console.log("Response body: ", body));
setTimeout(() => (responseObj.body.inProgress = false), 1500);