#angular
#angular
Вопрос:
Я получил неожиданную ошибку при реализации auth.guard в моем проекте Angular. Я получаю его при нажатии на ссылку, которая защищена 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
Ответ №1:
Ну, .includes
появляются ровно в двух местах в вашем скрипте, оба раза как this.url.includes
. После объявления свойства url
с ним больше ничего (в частности: присваивание) не происходит.
(И, кстати, вместо if (someBooleanExpression) return true; else return false;
этого вы можете просто return someBooleanExpression
.)
Ответ №2:
Внимательно посмотрите на AuthGuard.isLoginOrRegister (auth.guard.ts:30)
часть.
Вы должны обработать обработчик исключений, такой как показано ниже. Обратитесь к следующим // HERE
комментариям:
private isLoginOrRegister(): boolean {
// HERE
if (this.url amp;amp; (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();
}
Надеюсь, это вам поможет.
Ответ №3:
Публикую, просто чтобы объяснить, что произошло.
У вас есть эта строка
let url: string = state.url;
которое объявляет url переменной, ограниченной областью действия метода, в то время как свойство класса, объявленное выше, остается не инициализированным:
private url: string;
Поэтому переходим на
this.url = state.url;
должно решить это, поскольку сообщение об ошибке находится в этой строке
this.url.includes("login") || this.url.includes("register"))
и в нем говорится, что свойство равно нулю, что является истиной, вы его еще не инициализировали
Комментарии:
1. Помогло ли это вам, как вы говорили ранее?