Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • Router Guards in Angular 4 Application - Functionalities, Types & Examples

    • 1
    • 0
    • 0
    • 0
    • 0
    • 0
    • 1
    • 0
    • 1.66k
    Comment on it

    Route Guards in angular are defined as interfaces which decides navigation to a particular requested route should be allowed or not. This decision is made based on the boolean value returned from class which implemented one of various guards interface. In short they allow or restrict access to certain parts of navigation.

     

     

    Router Guards provide various kind of functionalities like 

     

    • Preventing users from accessing areas they are not allowed to access e.g a user might be logged in but not authorized to access target component.
    • Confirmation may be asked when user leave a certain area with unsaved changes.

     

    Router Guards Types

     

    • CanActivate :- Determines if a route can be visited by user or not.

     

    Example :-

     

    Consider parent component "AppComponent" and two child components "DashboardComponent" and "HomeComponent".

     

    dashboard.component.ts

     

    import { Component, OnInit } from '@angular/core';
    
    @Component({
     selector: 'app-dashboard',
     template: 'This is student dashboard only visited if student is logged in',
    })
    export class DashboardComponent {
    
     constructor() { }
    }

     

    home.component.ts

     

    import { Component, OnInit } from '@angular/core';
    
    @Component({
     selector: 'app-home',
     template: '<p>This is home component</p>',
    })
    export class HomeComponent {
    
     constructor() { }
    }

     

    app.component.ts

     

    import { Component,Inject } from '@angular/core';
    
    @Component({
     selector: 'app-root',
     template: '<router-outlet></router-outlet>',
    })
    export class AppComponent {
    
    }

     

    Create a simple service "StudentService"

     

    student.service.ts

     

    export class StudentService {
     isStudentLoggedIn(): boolean {
      return false;
     }
    }

     

    Above service method is always returning false so we are assuming student is not logged in.

     

    Guards in angular are implemented as services which return a boolean value true in case route is accessible by user and false if not. Guards are also capable of returning an Observable or Promise which is resolved to a boolean value this is the case when an API is called. Until the guard returns true or false, angular keeps the user waiting.


    Creating a simple CanActivate guard named "AuthGuard"

     

    authGuard.service.ts

     

    import { Injectable } from '@angular/core';
    import { Router, CanActivate } from '@angular/router';
    import { StudentService } from './student.service';
    
    @Injectable()
    export class AuthGuard implements CanActivate {
     constructor(private studentService: StudentService,private router:Router) {};
    
     canActivate() {
      if (this.studentService.isStudentLoggedIn()) {
       return true;
      } else {
       window.alert("You don't have permission to view this page")
       this.router.navigate(['home']);
       return false;
      }
     }
    }

     

    AuthGuard service is implementing "CanActivate" route guard interface. It returns true if student is logged in else return false and navigate it to "HomeComponent". Thus dashboard component can only be accessed if student is logged in.

     

    Include a routing file which performs necessary navigation.

     

    app.routing.ts

     

    import { Routes, RouterModule } from '@angular/router';
    import { NgModule } from '@angular/core';
    import { DashboardComponent } from './dashboard/dashboard.component';
    import { HomeComponent } from './home/home.component';
    import { AuthGuard } from './services/authGuard.service';
    
    const routes: Routes = [
     {
      path: '',
      redirectTo: 'home',
      pathMatch: 'full'
     },
     {
      path: 'home',
      component: HomeComponent,
     },
     {
      path: 'dashboard',
      component: DashboardComponent,
      canActivate:[AuthGuard]
     },
     {path: '**', component: HomeComponent}
    ];
    
    @NgModule({
     imports: [RouterModule.forRoot(routes)],
     exports: [RouterModule]
    })
    export class AppRoutingModule { }

     

    In above file AuthGuard is added to canActivate guards of dashboard route which signifies that whenever "dashboard" route is navigated, "AuthGuard" will be executed, wait for return value and "DashboardComponent" will only be executed if value returned is true.


    This AuthGuard and components are to be included in "AppModule".

     

    app.module.ts

     

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    import { DashboardComponent } from './dashboard/dashboard.component'
    import { HomeComponent } from './home/home.component'
    import { StudentService } from './services/student.service';
    import { AppRoutingModule } from './app.routing';
    import { AuthGuard } from './services/authGuard.service';
    
    @NgModule({
     declarations: [
      AppComponent,
      DashboardComponent,
      HomeComponent
     ],
     imports: [
      BrowserModule,
      AppRoutingModule
     ],
     providers: [StudentService,AuthGuard],
     bootstrap: [AppComponent]
    })
    export class AppModule { }

     

    index.html

     

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <base href="/">
      <meta name="viewport" content="width=device-width, initial-scale=1">
       <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
    </head>
    <body>
      <app-root></app-root>
    </body>
    </html>

     

    Whenever we try to navigate to the dashboard route we are blocked from doing so and a window alert is shown :-

     

     

    • CanActivateChild :- Determines if a route children can be visited by user or not.

     

    Example

     

    Create a new component "StudentComponent" which can be visited after dashboard i.e student is child component of dashboard component.


    student.component.ts

     

    import { Component, OnInit } from '@angular/core';
    
    @Component({
     selector: 'app-student',
     template: 'This is student component inside dashboard component',
    })
    export class StudentComponent implements OnInit {
    
     constructor() { }
    
     ngOnInit() {
     }
    }

     

    Creating a simple canActivateChild guard named "AuthGuardChildren"

     

    authGuardChildren.service.ts
     

    import { CanActivateChild } from '@angular/router';
    
    export class AuthGuardChildren implements CanActivateChild {
     constructor() {}
     canActivateChild() {
      return true;
     }
    }

     

    It is a simple guard which implements "CanActivateChild" route guard interface and returns true. Changes are made to following files :-

     

    app.module.ts

     

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    import { DashboardComponent } from './dashboard/dashboard.component'
    import { HomeComponent } from './home/home.component'
    import { StudentService } from './services/student.service';
    import { AppRoutingModule } from './app.routing';
    import { AuthGuard } from './services/authGuard.service';
    import { StudentComponent } from './student/student.component';
    import { AuthGuardChildren } from './services/authGuardChildren.service';
    
    @NgModule({
     declarations: [
      AppComponent,
      DashboardComponent,
      HomeComponent,
      StudentComponent
     ],
     imports: [
      BrowserModule,
      AppRoutingModule
     ],
     providers: [StudentService,AuthGuard,AuthGuardChildren],
     bootstrap: [AppComponent]
    })
    export class AppModule { }

     

    app.routing.ts

     

    import { Routes, RouterModule } from '@angular/router';
    import { NgModule } from '@angular/core';
    import { DashboardComponent } from './dashboard/dashboard.component';
    import { HomeComponent } from './home/home.component';
    import { StudentComponent } from './student/student.component';
    import { AuthGuard } from './services/authGuard.service';
    import { AuthGuardChildren } from './services/authGuardChildren.service';
    
    const routes: Routes = [
     {
      path: '',
      redirectTo: 'home',
      pathMatch: 'full'
     },
     {
      path: 'home',
      component: HomeComponent,
     },
     {
      path: 'dashboard',
      component: DashboardComponent,
      canActivate:[AuthGuard],
      canActivateChild:[AuthGuardChildren],
      children: [
      {path: 'student', component: StudentComponent},
     ]
    
     },
     {path: '**', component: HomeComponent}
    ];
    
    @NgModule({
     imports: [RouterModule.forRoot(routes)],
     exports: [RouterModule]
    })
    export class AppRoutingModule { }

     

    student.service.ts

     

    export class StudentService {
     isStudentLoggedIn(): boolean {
      return true;
     }
    }

     

    dashboard.component.ts

     

    import { Component, OnInit } from '@angular/core';
    
    @Component({
     selector: 'app-dashboard',
     template: 'This is student dashboard only visited if student is logged in <router-outlet></router-outlet>',
    })
    export class DashboardComponent {
    
     constructor() { }
    }


    Above we are assuming student is logged in, in routing file AuthGuardChildren is added to canActivateChild guards of dashboard route which signifies that whenever  "dashboard" route is navigated "AuthGuard" will be executed, wait for return value and "DashboardComponent" will only be executed if value returned is true. In turn whenever "StudentComponent" child routes is navigated,"AuthGuardChildren" will be executed to check if user has permission to access child route or not. Since in above example "AuthGuardChildren" will return true that is dashboard component has permission to access child route student component. When "/dashboard/student" url is navigated following output is obtained.

     

     

    • CanDeactivate :- This guard is used usually for warning users that they are leaving page with unsaved changes. But this guard only prevent from leaving page does not prevent from closing browser tab or navigating to another address. Actions are only prevented from the application itself.

     

    Example 

     

    Student.component.ts

     

    import { Component,ViewChild } from '@angular/core';
    
    @Component({
      selector: 'app-student',
      templateUrl: './student.component.html',
    })
    export class StudentComponent {
      @ViewChild('name') name: any;
    
      constructor() { }
    
       public unsavedChanges():boolean{
          if(this.name.dirty){
            return true;
          }
          return false;
        }
    }

     

    student.component.html

     

    <div class="container">
      <a [routerLink]="['/home']" >Home</a>
    	<div class="form-group">
      	<input type="text" class="form-control" [(ngModel)] = "Name"  #name="ngModel" placeholder="Name"/>
    	</div>	
    </div> 

     

    In student template we will take an input field "Name". Whenever this field is dirty and user changes its action by navigating to HomeComponent, the user will be asked for a confirmation to discard changes or not. This is performed via CanDeactivate router guard. 

     

    Create a simple CanDeactivate guard "AuthGuardDeactivate".

     

    authGuardDeactive.service.ts

     

    import { Injectable } from '@angular/core';
    import { CanDeactivate } from '@angular/router';
    import { StudentComponent } from '../student/student.component';
    
    @Injectable()
    export class AuthGuardDeactivate implements CanDeactivate<StudentComponent> {
     canDeactivate(component: StudentComponent): boolean {
      if (component.unsavedChanges()) {
       return confirm('Discard Changes?');
      }
      return true;
     }
    }


    AuthGuardDeactivate implements "CanDeactivate" route guard interface with component type being passed in between angle brackets "CanDeactivate<StudentComponent>". It is so that it knows the component type to be passed into component.unsavedChanges() function.
     
     
    Following changes are made to files for CanDeactive router guard.

     

    app.module.ts

     

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    import { DashboardComponent } from './dashboard/dashboard.component'
    import { HomeComponent } from './home/home.component'
    import { StudentService } from './services/student.service';
    import { AppRoutingModule } from './app.routing';
    import { AuthGuard } from './services/authGuard.service';
    import { StudentComponent } from './student/student.component';
    import { AuthGuardChildren } from './services/authGuardChildren.service';
    import { AuthGuardDeactivate } from './services/authGuardDeactivate.service';
    import { FormsModule } from '@angular/forms';
    
    @NgModule({
      declarations: [
        AppComponent,
        DashboardComponent,
        HomeComponent,
        StudentComponent,
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        FormsModule
      ],
      providers: [StudentService,AuthGuard,AuthGuardChildren,AuthGuardDeactivate],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

     

    app.routing.ts

     

    import { Routes, RouterModule } from '@angular/router';
    import { NgModule } from '@angular/core';
    import { DashboardComponent } from './dashboard/dashboard.component';
    import { HomeComponent } from './home/home.component';
    import { StudentComponent } from './student/student.component';
    import { AuthGuard } from './services/authGuard.service';
    import { AuthGuardChildren } from './services/authGuardChildren.service';
    import { AuthGuardDeactivate } from './services/authGuardDeactivate.service';
    import { TemplateformComponent } from './templateform/templateform.component';
    import { CanDeactivate } from '@angular/router'
    
    const routes: Routes = [
      {
        path: '',
        redirectTo: 'home',
        pathMatch: 'full'
      },
      {
        path: 'home',
        component: HomeComponent,
      },
      {
        path: 'dashboard',
        component: DashboardComponent,
        canActivate:[AuthGuard],
        canActivateChild:[AuthGuardChildren],
        children: [
        { path: 'student', component: StudentComponent,canDeactivate: [AuthGuardDeactivate] },
      ]
      },
      {path: '**', component: HomeComponent}
    ];
    @NgModule({
      imports: [RouterModule.forRoot(routes)],
      exports: [RouterModule]
    })
    export class AppRoutingModule { }

     

    canDeactivate guard is added to dashboard child component student. 

     

    When /dashboard/student is navigated and "Name" input field is dirted then component.unsavedChanges() will return true as a result a confirmation alert window is shown asking user to discard changes.  

     

     

    If no changes are made to input field then user is navigated to "HomeComponent".

     

    Router Guards in Angular 4 Application - Functionalities, Types & Examples

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: