user3154990 user3154990 - 1 month ago 162
TypeScript Question

Can I call retry after retryWhen in rxJS angular2

I want to call retry after retryWhen which is not working, how can I call same observable after retryWhen. My code is not reaching retry.

.retryWhen(error => this.refreshToken()).retry(3)
.map((res: Response) => {
this.inspections = res.json();
return this.inspections;
});


here is ny refreshToken() function

refreshToken(error$:any): Observable {

return error$.flatMap((err:Error) => {
console.log("refreshing token");
const body: string = 'grant_type=refresh_token&refresh_token=' + localStorage.getItem("refresh_token");
const headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');

const options = new RequestOptions({ headers: headers });

// Make the refresh call as normal
return this.http.post('https://loginqa.test.com/as/token.oauth2', body, options)
}).map((res: Response) => {
return res.json();

})

.do((resp:Response) => {
var resultsToken=resp.json();
alert("testing refresh_token");
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
localStorage.setItem("access_token", resultsToken.access_token);
localStorage.setItem("refresh_token", resultsToken.refresh_token);

}

Answer

The problem is that your refreshToken function doesn't actually handle or emit an error. Which is what it would need to do in order to reach the retry.

In your subscribe block you aren't subscribing to the throw operator so the error is never going anywhere.

I would refactor the refreshToken so that it actually emits an error if it fails.

// Pass in the error stream so you are actually processing when there is an
// exception
refreshToken(error$): Observable<any> {

  return error$.flatMap(err => {
    console.log("refreshing token");
    const refreshToken = localStorage.getItem('refreshToken');
    const body: string = `grant_type=refresh_token&refresh_token=${refreshToken}`;
    const headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');

    const options = new RequestOptions({ headers: headers });

    // Make the refresh call as normal
    return this.http.post('https://fedqa.test.com/as/token.oauth2', body, options);
  })
  .map(res => res.json())
  .do(resp => {
    // If there is no error, this will emit a next value
    // and which will trigger the retry
    // An error triggers, then this will not run and the retryWhen
    // will skip ahead to the retry operator.
    localStorage.removeItem('access_token');
    localStorage.removeItem('refresh_token');
    localStorage.setItem("access_token", resp.access_token);
    localStorage.setItem("refresh_token", resp.refresh_token);
    localStorage.setItem("expires_in", resp.expires_in);
  });


}

Then use it like:

.retryWhen(error$ => this.refreshToken(error$)).retry(3);