角度/离子HttpRequest拦截器。如何使用AlertController重复请求

时间:2018-04-14 12:56:45

标签: angular ionic-framework observable

目前我有以下请求拦截器,它可以完美运行。它添加了身份验证令牌并处理响应。

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
  constructor(
    public injector: Injector,
    public alertCtrl: AlertController,
    public events: Events
  ) {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    let token = this.injector.get(AuthProvider).authToken;
    let request = req;
    if (token) {
      request = req.clone({
        headers: req.headers.set("Authorization", "Bearer " + token)
      });
    }
    return next
      .handle(request)
      .map(res => {
        if (res instanceof HttpResponse) {
          return res;
        }
      })
      .catch(err => {
        if (err instanceof HttpErrorResponse) {
          if (err.status === 0) {
            let alert = this.alertCtrl.create({
              title: "Server Unreachable",
              subTitle: "Can't connect to the server. Please try again later.",
              buttons: ["OK"]
            });
            alert.present();
          } else if (err.status === 401) {
            let alert = this.alertCtrl.create({
              title: "Unauthorized Access",
              message: "Please Login and try again",
              buttons: [
                {
                  text: "Cancel",
                  role: "cancel"
                },
                {
                  text: "Login",
                  handler: () => {
                    this.events.publish("logout");
                  }
                }
              ]
            });
            alert.present();
          } else {
            let alert = this.alertCtrl.create({
              title: err.statusText,
              subTitle:
                err.hasOwnProperty("error") &&
                err.error.hasOwnProperty("message")
                  ? err.error.message
                  : err.message,
              buttons: ["OK"]
            });
            alert.present();
          }
          console.log(err);
        }
        return Observable.of(err);
      });
  }
}

但我很好奇是否有可能重新发送请求...例如,如果“服务器无法访问”我正在显示而不是警报确认框,它可以重新发送请求。

1 个答案:

答案 0 :(得分:1)

Retry is the operator you are looking for

import { retry } 'rxjs/operators';

return next
  .handle(request)    
  ...
  .retry(2);

更新回答Live Example Using ngx-bootstrap, retryWhen

const observable$ = this.appService.purchase('someurl', book)
  .pipe(
    catchError(err => {
      this.modalRef = this.modalService.show(this.modal)            
      return this.modalService.onHide.pipe(take(1), mapTo(err));
    }),
    tap(err => {
      if (this.tryAgain) {
        throw err;
      }
    }),
    retryWhen(errors => {
      return errors
        .pipe(
          tap(val => console.log('retryWhen', val)),
        )
      })
    );

observable$.subscribe(
  res => console.log('sucess: ', res), 
  err => {
    console.log('error: ', err);
  });