在Angular项目中实施auth.guard时遇到意外错误。 我是在受auth.guard保护的链接点击上得到的。
auth.guard.ts
import { Injectable } from "@angular/core";
import {
CanActivate,
Router,
ActivatedRouteSnapshot,
RouterStateSnapshot
} from "@angular/router";
import { AuthService } from "./auth.service";
@Injectable()
export class AuthGuard implements CanActivate {
private url: string;
constructor(private auth: AuthService, private router: Router) {}
private handleAuthState(): boolean {
if (this.isLoginOrRegister()) {
this.router.navigate(["/rentals"]);
return false;
}
return true;
}
private handleNotAuthState(): boolean {
if (this.isLoginOrRegister()) {
return true;
}
this.router.navigate(["/login"]);
return false;
}
private isLoginOrRegister(): boolean {
if (this.url.includes("login") || this.url.includes("register")) {
return true;
}
return false;
}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
let url: string = state.url;
if (this.auth.isAuthenticated()) {
return this.handleAuthState();
}
return this.handleNotAuthState();
}
}
控制台错误
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'includes' of undefined
TypeError: Cannot read property 'includes' of undefined
at AuthGuard.push../src/app/auth/shared/auth.guard.ts.AuthGuard.isLoginOrRegister (auth.guard.ts:30)
at AuthGuard.push../src/app/auth/shared/auth.guard.ts.AuthGuard.handleAuthState (auth.guard.ts:16)
at AuthGuard.push../src/app/auth/shared/auth.guard.ts.AuthGuard.canActivate (auth.guard.ts:43)
at router.js:3103
at Observable._subscribe (defer.js:9)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:43)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:29)
at TakeOperator.push../node_modules/rxjs/_esm5/internal/operators/take.js.TakeOperator.call (take.js:24)
at Observable.push../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:24)
at subscribeTo.js:21
at resolvePromise (zone.js:831)
at resolvePromise (zone.js:788)
at zone.js:892
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:423)
at Object.onInvokeTask (core.js:17290)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:422)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:195)
at drainMicroTaskQueue (zone.js:601)
at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:502)
at invokeTask (zone.js:1744)
defaultErrorLogger @ core.js:15724
push../node_modules/@angular/core/fesm5/core.js.ErrorHandler.handleError @ core.js:15772
next @ core.js:17771
schedulerFn @ core.js:13515
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub @ Subscriber.js:196
push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next @ Subscriber.js:134
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next @ Subscriber.js:77
push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next @ Subscriber.js:54
push../node_modules/rxjs/_esm5/internal/Subject.js.Subject.next @ Subject.js:47
push../node_modules/@angular/core/fesm5/core.js.EventEmitter.emit @ core.js:13499
(anonymous) @ core.js:17321
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke @ zone.js:391
push../node_modules/zone.js/dist/zone.js.Zone.run @ zone.js:150
push../node_modules/@angular/core/fesm5/core.js.NgZone.runOutsideAngular @ core.js:17258
onHandleError @ core.js:17321
push../node_modules/zone.js/dist/zone.js.ZoneDelegate.handleError @ zone.js:395
push../node_modules/zone.js/dist/zone.js.Zone.runGuarded @ zone.js:164
_loop_1 @ zone.js:694
api.microtaskDrainDone @ zone.js:703
drainMicroTaskQueue @ zone.js:608
push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask @ zone.js:502
invokeTask @ zone.js:1744
globalZoneAwareCallback @ zone.js:1770
答案 0 :(得分:0)
好吧,.includes
在脚本中恰好出现在两个位置,两次都以this.url.includes
出现。声明属性url
后,再也没有其他事情(尤其是赋值)。
(顺便说一句,您可以简单地if (someBooleanExpression) return true; else return false;
来代替return someBooleanExpression
。)
答案 1 :(得分:0)
发布,只是为了说明发生了什么。
您有这行
let url: string = state.url;
声明方法范围的变量url,而上面声明的class属性保持未初始化:
private url: string;
因此更改为
this.url = state.url;
应解决此问题,因为错误消息在此行
this.url.includes("login") || this.url.includes("register"))
它说该属性为null,这是对的,您尚未初始化
答案 2 :(得分:0)
仔细研究AuthGuard.isLoginOrRegister (auth.guard.ts:30)
部分。
您应处理如下的异常处理程序。
请参考以下// HERE
条评论:
private isLoginOrRegister(): boolean {
// HERE
if (this.url && (this.url.includes("login") || this.url.includes("register"))) {
return true;
}
return false;
}
...
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
// HERE
this.url = state.url;
if (this.auth.isAuthenticated()) {
return this.handleAuthState();
}
return this.handleNotAuthState();
}
希望对您有帮助。