Angular中HttpInterceptor使用NzMessageService报错的解决方法
解决Angular HttpInterceptor中使用NzMessageService的NullInjectorError问题
错误原因
HttpInterceptor在Angular应用启动早期就会被实例化,而NzMessageService依赖Overlay等与DOM相关的服务,这些服务无法在应用启动的早期阶段完成注入,直接在拦截器构造函数中注入NzMessageService会导致依赖链断裂,触发找不到提供者的错误。
解决方法
方法一:通过Injector延迟获取NzMessageService
修改interceptor.service.ts,使用Injector在需要使用服务时再获取实例,避开启动阶段的注入限制:
import { Injectable, Injector } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { NzMessageService } from 'ng-zorro-antd/message'; @Injectable() export class InterceptorService implements HttpInterceptor { private messageService: NzMessageService; constructor(private injector: Injector) { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe(catchError((err) => { // 延迟初始化服务,避免启动时注入冲突 if (!this.messageService) { this.messageService = this.injector.get(NzMessageService); } this.messageService.create("error", "error message", { nzDuration: 4000 }); return throwError(err); })); } }
方法二:使用Angular的inject函数(Angular 14+)
在intercept方法内直接调用inject函数获取NzMessageService实例,该方法会在合适的上下文环境中完成服务注入:
import { inject } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { catchError } from 'rxjs/operators'; import { NzMessageService } from 'ng-zorro-antd/message'; @Injectable() export class InterceptorService implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req).pipe(catchError((err) => { const messageService = inject(NzMessageService); messageService.create("error", "error message", { nzDuration: 4000 }); return throwError(err); })); } }
额外优化:清理AppModule冗余配置
由于NzMessageServiceModule已经注册了NzMessageService的提供者,可移除app.module.ts中providers数组里的NzMessageService,避免重复注册:
@NgModule({ declarations: [ AppComponent ], imports: [ NzMessageServiceModule ], providers: [ {provide: HTTP_INTERCEPTORS, useClass: InterceptorService, multi: true}, ], bootstrap: [AppComponent] }) export class AppModule { }
内容的提问来源于stack exchange,提问作者SSSH
相关产品推荐
相关产品推荐

