Angular 2中服务内注入另一服务调用时报undefined错误如何解决
问题原因
核心问题是GlobalService中的handleError方法被调用时this指向丢失,没有指向GlobalService的实例,导致this.notification_srv读取为undefined。
这种场景90%以上出现在你将handleError作为回调函数直接传给RxJS的catchError操作符时:函数独立执行时this会绑定到全局上下文(严格模式下为undefined),自然无法读取注入的NotificationService实例。
修复方案
提供三种常用修复方式,任选一种即可:
- 方案1:将
handleError改为箭头函数定义(最推荐,无需修改调用侧代码)
修改GlobalService中的方法定义,箭头函数会继承外层作用域的this指向,不会随调用方式变更:
// GlobalService 中修改handleError定义 public handleError = (error: HttpErrorResponse) => { if (error.status === 0) { console.error('An error occurred:', error.error); this.notification_srv.warn(`An error occurred: ${error.error}`) } else { console.error( `Backend returned code ${error.status}, body was: `, error.error); this.notification_srv.warn('Backend returned code') } return throwError('Something bad happened; please try again later.'); }
- 方案2:调用时手动绑定this指向
在传递handleError作为回调的位置,用bind方法绑定当前GlobalService实例作为this:
// 例如调用catchError的位置 yourApiCall.pipe( catchError(this.handleError.bind(this)) ).subscribe()
- 方案3:用匿名箭头函数包裹方法调用
传递回调时用箭头函数包裹一层,保证handleError是作为实例方法被调用:
yourApiCall.pipe( catchError(err => this.handleError(err)) ).subscribe()
额外排查项
如果修改后仍然报错,可排查以下两点:
- 检查项目根模块
AppModule中是否正确导入了MatSnackBarModule,NotificationService依赖的MatSnackBar需要该模块提供 - 检查
@services/notification.service的路径别名是否配置正确,确认导入的NotificationService是你定义的对应服务
内容的提问来源于stack exchange,提问作者4aLifeTime
相关产品推荐
相关产品推荐

