Categories
Uncategorized

Using multiple guards for a route in Angular

The canActivate( ) method which should be overridden, should return only one of the following types

  • Observable<boolean>
  • Promise<boolean>
  • boolean

The multiple routes work like an ‘&&’ condition in javascript, i.e., angular won’t execute the later guards, if the first one fails.

app-routing.module

import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import {HomeComponent} from './home.component';
import {GuardOne} from './guard-one.guard';
import {GuardTwo} from './guard-two.guard';

const routes: Routes = [
    {
        path: '',
        redirectTo: '/home',
        pathMatch: 'full'
    },
    {
        path: 'home',
        canActivate: [GuardOne, GuardTwo],
        component: HomeComponent,
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule {
}

guard-one.guard

import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';

import {LoginService} from './user.service';

@Injectable()
export class GuardOne implements CanActivate {

    constructor(private router: Router, private userLoginSer: LoginService) {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        if (!this.userLoginSer.user) {
         // you can send them to some other route like this.
         // this.router.navigate(['/nonUserHome']);
            return false;
        } else {
            return true;
        }
    }
}

guard-two.guard

import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';

import {LoginService} from './user.service';

@Injectable()
export class GuardTwo implements CanActivate {

    constructor(private router: Router, private userLoginSer: LoginService) {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        if (!this.userLoginSer.login) {
         // you can send them to some other route like this.
         // this.router.navigate(['/login']);
            return false;
        } else {
            return true;
        }
    }
}

The login service that is being used above can be somewhat like this:

guard-two.guard

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Injectable()
export class LoginService {
    login = true;
    user = true;

    constructor(private http: HttpClient) {
    }
}

For these files to work, you need to add them to the app.module.ts and also use in the main component where you would like to use the router.