未捕获(承诺):TypeError:无法读取未定义的属性“ includes”

时间:2019-04-20 12:56:46

标签: angular

在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

error in the console

3 个答案:

答案 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();
}

希望对您有帮助。