【问题标题】:Can't inject Router into HttpInterceptor (Angular 7)无法将路由器注入 HttpInterceptor (Angular 7)
【发布时间】:2019-09-19 07:24:08
【问题描述】:

我想将 Angular 路由器注入到我的 HttpInterceptor 中。不幸的是,在浏览器控制台中抛出了以下错误:

TypeError: this.router 未定义

我已经像往常一样将它添加到我的构造函数中:

constructor (private router: Router) {

}

此外,我在 app.module.ts 内的 providers 数组中做了以下操作:

{
  provide: HTTP_INTERCEPTORS,
  useClass: MyService,
  multi: true,
  deps: [Router]
}

我想在我的错误处理程序的 if 语句中使用当前 url 来为不同的路由提供特定的功能:

myErrorHandler(error: HttpErrorResponse) {
   if (this.router.url === 'test') {
     // do something
   } else {
     return throwError(error).pipe(
       // do something
     );
   }
}

我做错了什么?

【问题讨论】:

  • 你能提供更多的上下文吗?问题中的代码看起来不错。
  • @Lemon 我已经更新了我的问题。我想在我的拦截器中获取当前路由(url)并在错误处理程序中使用它。
  • @Codehan25 你设法解决了这个问题吗?我在使用相同的设置时遇到了同样的问题。

标签: angular angular-router angular-httpclient angular-http-interceptors angular-httpclient-interceptors


【解决方案1】:

你做过吗?太明显了?

import { Router } from "@angular/router";

【讨论】:

  • 当然 :) 我认为拦截器有一些特别之处,但我在文档中找不到任何内容。
【解决方案2】:

您可以尝试使用注射器。

constructor(inj: Injector) {
this.router = inj.get(AuthService) }

您应该注意,无法导入包含 httpClientModule 的服务以避免循环依赖。

【讨论】:

    【解决方案3】:

    我从另一个相关话题中找到了答案:Angular 6 Service is undefined after injecting in Interceptor

    基本上,注入的构造函数变量在您传递给catchError 函数的函数中不可用。您需要像这样在“拦截方法”中直接访问router

    constructor(private router: Router) {
    }
    
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            catchError((errorResponse: HttpErrorResponse) => {
                // this.router is defined here
            })
        );
    }
    

    问题似乎在于catchError。如果您在 interceptcatchError 函数中打印当前范围 this,您将分别获得 MyInterceptorCatchSubscriber。 CatchSubscriber 不提供this.router。您仍然可以通过在拦截器类中添加私有方法来使用单独的函数:

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(
            catchError((errorResponse: HttpErrorResponse) => {
                this.handleError(errorResponse);
            })
        );
    }
    
    private handleError(errorResponse: HttpErrorResponse) {
         // this.router is defined here
    }
    

    总结一下:

    catchError(this.handleError)  // does not work because of different scope
    
    catchError(err => this.handleError(err))  // works because of same scope
    

    【讨论】:

    • 这让我免于头痛。
    猜你喜欢
    • 2019-03-08
    • 2019-07-27
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    相关资源
    最近更新 更多