Retry query if receive empty result from http.get Angular with RJXS Operators

Viewed 2093

I have a query in an Angular service, sometimes I receive an empty array and I want to force the query to be done again in this case

let request = this.http.post(this.searchlUrl, payload).pipe(
          retryWhen(errors => errors.pipe(delay(1000), take(2), concat(throwError("Error Data")))), 
          map( res => {
            // If receive res['hotels'] == [] I want to force error
            return res; 
          })
        ).subscribe(res => {
            // Do Something when everything is ok
        }, err => {
            // Do Something on error
        });
      });

I am working with retryWhen to make a new request if there is an error (I wait 1 second). My approach is to force an error when receiving empty so that the RetryWhen is activated but I don't know how to do it, and I don't know what is the best practice to force a reconsultation when receiving empty.

2 Answers

The main problem is the order of operators. retryWhen reacts only to error notifications so you need to throw the error before retryWhen:

this.http.post(this.searchlUrl, payload).pipe(
  map(response => {
    if (something) {
      throw new Error(); // Will be caught by `map` and reemitted as an error notification.
    }
    return response;
  }),
  retryWhen(errors => errors.pipe(take(2), delay(1000))),
).subscribe(...);

Live demo: https://stackblitz.com/edit/rxjs-cmh1wd

Here's a simple example of a retry operation that might help you on the way. I use of to create the observable. Replace it with your api call.

private resultToReturn: string[] = [];

  ngOnInit() {
    var request = 
      of(this.resultToReturn).pipe(
        map(result => {
          if (result.length === 0) {
            this.resultToReturn.push("some value");
            console.log("Didn't get any data!")
            throw new Error();
          }
          return result;
        }),
        retryWhen(errors => {
          console.log("Retrying!")
          return of(this.resultToReturn)})
      );

      request.subscribe(x => console.log(x[0]));
  }
Related