Angular:Auth Service中BehaviorSubject始终为undefined的问题求助
问题原因
直接将handleAuthentication方法作为参数传给tap操作符时,函数的this上下文会丢失,不再指向AuthService实例,导致this.user变成undefined。JavaScript中普通函数的this由调用方式决定,当tap内部调用该函数时,this默认指向全局对象(严格模式下为undefined)。
修复方案
提供三种可行修复方式,按推荐度排序:
方案1:用箭头函数包裹调用
在tap中用箭头函数调用handleAuthentication,箭头函数会继承外部的this上下文,同时同步修复handleError的上下文问题:
signup(email: string, password: string) { // ... 原有HTTP请求逻辑 ).pipe( catchError((err) => this.handleError(err)), tap((res) => this.handleAuthentication(res)) ) } login(email: string, password: string) { // ... 原有HTTP请求逻辑 ).pipe( catchError((err) => this.handleError(err)), tap((res) => this.handleAuthentication(res)) ) }
方案2:在构造函数中绑定this
在服务的构造函数里,将handleAuthentication和handleError的this绑定到服务实例,之后就能直接传递方法引用:
constructor( private http: HttpClient ) { this.handleAuthentication = this.handleAuthentication.bind(this); this.handleError = this.handleError.bind(this); } // signup和login方法保持原有写法即可 signup(email: string, password: string) { // ... ).pipe( catchError(this.handleError), tap(this.handleAuthentication) ) } login(email: string, password: string) { // ... ).pipe( catchError(this.handleError), tap(this.handleAuthentication) ) }
方案3:将方法改为箭头函数
把handleAuthentication和handleError定义为箭头函数,箭头函数的this始终指向定义时的上下文(即AuthService实例):
private handleAuthentication = (response: AuthResponseData) => { const { email, localId, idToken, expiresIn } = response const expires = new Date(new Date().getTime() + +expiresIn * 1000) const user = new User(email, localId, idToken, expires) this.user.next(user) } private handleError = (errorResponse: HttpErrorResponse) => { // ... 原有错误处理逻辑 } // signup和login方法保持原有写法即可
额外提醒
handleError方法同样存在this上下文丢失的问题,所以所有修复方案中都同步处理了它,避免后续在错误处理逻辑中用到服务属性或方法时出现同样的undefined错误。
内容的提问来源于stack exchange,提问作者Jonathan Sigg
相关产品推荐
相关产品推荐

