angularrxjsobservableretrywhen

How to update the source when use retrywhen RxJs


I'm doing a request to an API to create an order, it's probably got an error when trying to create the order with the same code because the method generateCode() is a random generator!

When performing retries, it uses the same source, which means, uses the same code in the request, it's not calling again the method sendRequest() which creates a new order with a new code!

Unfortunately, I can't change the method generateCode() to get unrepeated codes! I have to use this approach to generate random codes!

this.sendRequest()
      .pipe(
        this.retryStrategy(),
        tap((response) => {
          ...
        }),
        catchError((error) => {
          return EMPTY;
        })
      ).subscribe();

sendRequest(): Observable<any> {
    let order = {
       code: generateCode()
    };
    return this.service.createOrder(order);
  }

retryStrategy(delayDurationMs: number = 1000, maxRetryAttempts: number = 3) {
    return (src: Observable<any>) => src.pipe(
      retryWhen((errors: Observable<any>) => errors.pipe(
        mergeMap((error, i) => {
          const retryAttempt = i + 1;
          console.log('%c retryAttempt: ' + retryAttempt, 'background: #fff; color: red');

          if (maxRetryAttempts > retryAttempt) {
            return timer(delayDurationMs);
          }

          return throwError(error)
        }),
        finalize(() => console.log('%c retry process has done!', 'background: #222; color: #bada55'))
      ))
    )
  }

Solution

  • Try warp with defer in you sendRequest method, which should re run everytime when retry

    sendRequest(): Observable<any> defer(()=>{
        let order = {
           code: generateCode()
        };
        return this.service.createOrder(order);
      })