0

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)
);
LukeP
  • 1,505
  • 1
  • 16
  • 25

1 Answers1

2

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));

https://codepen.io/fancheung/pen/gqjawe

Fan Cheung
  • 10,745
  • 3
  • 17
  • 39
  • Thanks, I get the same result in console with the modified code though. I have created a stackblitz to show the results: https://stackblitz.com/edit/typescript-us8viy – LukeP Feb 12 '19 at 17:46
  • Here is an even more simple example that doesn't work. It's just a simple `retry` that doesn't ever retry. What am I missing here? https://stackblitz.com/edit/typescript-hfcdyq – LukeP Feb 12 '19 at 18:25
  • Forgot to change to defer, promise will execute immediately and won't get repeated. updated the answer. – Fan Cheung Feb 13 '19 at 07:48