Angular 2 Observable.retryWhen doesn't include

2019-08-06 19:19发布

I am trying to get my code updated so that I am able to use refresh tokens to keep a user logged in. I intend to do this using the Observable.retryWhen method. However I am running into an issue where the error being passed to my retry method has a type of Subject instead of Response like I expected and have gotten in the past. This is an issue because I need to check if the status is a 401 and Subject doesn't include the status of the response. Also the catch works as expected passing a Response object to the handleError method.

http.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

import { Http, Headers, RequestOptions, Response } from '@angular/http';

@Injectable()
export class HttpService {

  constructor(
    private http: Http
  ) { }

  public get(url: string, headers?: Headers): Observable<any> {
    return this.http.get(url, this.getHeaders(headers))
      .map(this.extractData)
      .retryWhen(this.handleRetry)
      .catch(this.handleError);
  }

  private handleRetry(error: Response): Observable<any> {
    if (error.status === 401) { // I can't get past here because error doesn't include status and is the wrong type.
      ...
    }
  }
}

Error equals

Subject {
  closed: false
  hasError: false
  isStopped: false
  observers: Array(0)
  thrownError: null
  _isScalar: false
}

While I expect error to equal something similar to:

Response {
  headers: Headers
  ok: false
  status: 401
  statusText: "OK"
  type: 2
  url: "..."
  _body: ""
}

1条回答
Melony?
2楼-- · 2019-08-06 19:45

The function passed to retryWhen does not receive an Error; it receives an Observable<Error> argument. That is why you are seeing a Subject.

The logic in your handleRetry function needs to be composed into an observable, from within which any effected errors can be inspected. mergeMap could be used to retry some errors and fail others. For example:

private handleRetry(errors: Observable<Response>): Observable<any> {

  return errors.mergeMap(error => {

    if (error.status === 401) {

      // Add an authorization header, perhaps.
      // ...
      // Emit anything (the error instance, for example) to retry:
      return Observable.of(error);

    } else {

      // Throw the error to give up retrying:
      return Observable.throw(error);
    }
  });
}
查看更多
登录 后发表回答