I feel like I'm missing something really simple here. I'm trying to create a simple retry for fetch but only the code in the retryWhen
is getting executed. I'm using React so i dont have the this.http.get
convenience. Perhaps it's an issue with from(/*promise*/)
? I was trying to base the retry logic off of this post.
This is what I would expect to see:
Getting data from fetch...
In the retryWhen
In the interval
/* repeat the previous 3 lines 3x times including the Fetch */
Giving up
Instead I get:
Getting data from fetch...
In the retryWhen
In the interval...
In the interval...
In the interval...
In the interval...
Giving up
So it is just repeating the code in he retryWhen interval but not repeating the original fetchData call. I'm probably missing something fundamental to my RXJS knowledge.
Here's the test code:
const fetchData = new Promise((res, rej) => {
console.log("Getting data from fetch...");
rej(); // just fail immediately to test the retry
});
const source = from(fetchData)
.pipe(
retryWhen(_ => {
console.log("In the retryWhen");
return interval(1000).pipe(
tap(_ => console.log("In the interval...")),
flatMap(count => count == 3 ? throwError("Giving up") : of(count))
)
}));
source.subscribe(
result => console.log(result),
err => console.log(err)
);
Change to the code below see if it works. retryWhen
pass you a error stream which will keep emitting if there is error. you return a timer
to specify the delay in between each retry inside retryWhen
. After the delay it will retry the source observable for you
const fetchData = defer(() => new Promise((res, rej) => {
console.log('in promise')
rej("Failed to fetch data");
// fail the first 2 times
}) );
const source = fetchData.pipe(
retryWhen(err => {
let count = 0;
console.log("In the retryWhen");
return err.pipe(
tap(_ => {
count++;
console.log("In the interval...");
}),
mergeMap(_ => (count == 2 ? throwError("Giving up") : timer(2000)))
);
})
);
source.subscribe(result => console.log(result), err => console.warn(err));