angulartypescriptcanactivate

Problem of ending return statement on canActivate


I have a problem when I use CanActivate method: error ts2366 "Function lacks ending return statement and return type does not include undefined" appears.

Following my code:

import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthGuard implements CanActivate {

  constructor(private authService: AuthService,
              private router: Router) { }

  canActivate(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
    if (this.authService.isAuth) {
      return true;
    } else {
      this.router.navigate(['/auth']);
    }
  }
}

I tried to add '| undefined' after boolean but an other error told me it was incompatible with CanActivate.

Do you have any idea to solve it ?

Thanks by advance for your help.


Solution

  • You are supposed to return either a boolean or a UrlTree from canActivate. If you return the UrlTree it will deal with the navigation for you, so you don't need to call this.router.navigate yourself (see https://angular.io/api/router/CanActivate)

    Your code might look like this:

    import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from '@angular/router';
    import { Observable } from 'rxjs';
    import { AuthService } from './auth.service';
    import { Injectable } from '@angular/core';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
    
      constructor(private authService: AuthService,
                  private router: Router) { }
    
      canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
        if (this.authService.isAuth) {
          return true;
        } else {
          return this.router.parseUrl('/auth');
        }
      }
    }