What are Route Guards, Pre-loads and Lazy-loading in Angular?

Angular comes with a bunch of inbuilt features, which can be used fully to provide authentication, boost your application’s page, loading speed, etc.

In this blog, we will be going to cover few angular components which will help you in improving user experience by enhancing the bootstrap and startup process. Read also about Steps to Getting Better at Angular Development

What is Route Guards?

Angular’s route guards are a type of interface that will tell the router whether it should navigate to the requested route or not. The decision of accessing that requested route is made by a class that implements the given guard interface. There are five types of guard available in angular and each of them is called in a particular sequence. router behavior will change according to the selected guard. 

  • CanActivate
  • CanActivateChild
  • CanDeActivate
  • CanLoad
  • Resolve

Routing based on Token Expiration

One of the best ways to secure your Angular application is by using JSON Web Tokens (JWT). You can check the token’s expiration time and decide whether the route should be accessed or not.

To implement the RouteGuard interface in your application you will have to create a method in your authentication service which will check if the user is authenticated or not. For the purposes of stateless authentication with JWT, it simply checks token expiration status. We will have to use JwtHelperService class from angular2-jwt in our application. Contact our angular development professionals to know more

Step 1: We will have to add the following code in our application terminal:

npm install --save @auth0/angular-jwt

Now the required package is installed in our project, so that we can implement our logic in the next step: 

Step 2: Add the following code in your auto service file

Auth.service.cs:

import { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
@Injectable()
export class AuthService {
  constructor(public jwtHelper: JwtHelperService) {}
  // ...
  public isAuthenticated(): boolean {
    const token = localStorage.getItem('token');
    // will  Check whether the token is expired or not and return
    // true or false
    return !this.jwtHelper.isTokenExpired(token);
  }
}

NOTE: We are assuming that you have implemented JWT and stored token in Local Storage.

Step 3: Create a new service and implements route guard

Add following code in that service:

import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
@Injectable()
export class AuthGuardService implements CanActivate {
  constructor(public auth: AuthService, public router: Router) {}
  canActivate(): boolean {
    if (!this.auth.isAuthenticated()) {
      this.router.navigate(['login']);
      return false;
    }
    return true;
  }
}

We can decide whether the requested route should be navigated or not by using this canActivate() method which will return a Boolean value.

Step 4: Everything is almost done now you just have to add a guard to the route which you want to protect

import { Routes, CanActivate } from '@angular/router';
import { ProfileComponent } from './profile/profile.component';
import { 
  AuthGuardService as AuthGuard 
} from './auth/auth-guard.service';
export const ROUTES: Routes = [
  { path: '', component: HomeComponent },
  { 
    path: 'homepage',
    component: HomePageComponent,
    canActivate: [AuthGuard] 
  },
  { path: '**', redirectTo: '' }
];

Now, whenever the homepage path is called, route guard will check canActivate method and will decide whether it should navigate to that route or not.

What is Pre-loading in Angular?

Pre-Loading is a loading strategy which will load all the module immediately after all eager loaded modules are ready. This will eliminate the possible latency when you are loading a lazy-loaded module because the initial module(s) get loaded first, pre-loading still has the benefit of faster initial loading of our application.

The default way of pre-loading in angular is PreLoadAllModule, which means that all lazy-loaded modules will be preloaded. You will have lazy-loading available in your project for that. If you don’t want to preload all lazy-loaded modules you can use the second method which is called CustomPreLoading.

When to use PreLoadAllModule and when CustomProLoading: let’s assume you have added lazy loading in your project and if you have a scenario where some of your lazy loaded modules don’t come in interaction with the user more often than you should use CustomProLoading else you can go for PreLoadAllModule.

To see the Pre-loading example first we will have to understand lazy-loading.

What is Lazy-Loading in Angular?

Lazy loading is an optimization technique to render your application faster and provide better performance. Instead of loading all modules/pages at the starting of your application, lazy loading will load only the required section and will delay the remaining module until it’s needed/called by the user.

Simple lazy loading example:

AppRouting.Module.ts:

const routes: Routes = [
  {
    path: 'items',
    loadChildren: () => import('./product/product.module').then(m => m.ProductModule)
    }
];

Product-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: ProductComponent
  }
];

In this example, the product component is set on lazy loading mode, so it will not be loaded with its parent’s page.

Now, Let’s take a real-life project example with lazy loading and PreLoading.

import { CarOwnerModule } from './../car-owner/car-owner.module';
import { AppPage } from './../../../e2e/src/app.po';
import { AdminModule } from './../admin/admin/admin.module';
import { AdminDashboardComponent } from '../admin/admin/dashboard/admin-dashboard.component';
import { AdminUserRequestesComponent } from '../admin/admin/user-requestes/admin-user-request														es.component';
import { CommonSidebarComponent } from './common-sidebar.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule, PreloadAllModules, PreloadingStrategy } from '@angular/router';
import { UserRegisterComponent } from '../user-register/user-register.component';
 
const routes: Routes = [
  {
    path: '',
    component: CommonSidebarComponent,
    children: [
      {
        path: 'userRegister',
        component: UserRegisterComponent
      },
      {
        path:'Admin',
        loadChildren: () => import('../admin/admin/admin.module').then(k => k.AdminModule)
      },
      {
        path:'client',
        loadChildren :() =>import('../client/client.module').then(k=> k.ClientModule)
      },
      {
        path:'carOwner',
        loadChildren: ()=>import('../car-owner/car-owner.module').then(k=>CarOwnerModule)
      },
      {
        path:'employee',
        loadChildren:()=> import('../employee/employee.module').then(k=>k.EmployeeModule)
      }
    ]
  }
];
@NgModule({
  imports: [RouterModule.forChild(routes),{preloadingStrategy : PreloadAllModules}],
  exports: [RouterModule]
})
export class CommonSidebarRoutingModule { }

This is an example of a sidebar menu of our last project, which included a bunch of role modules and we didn’t need all module at stating until it’s called by the user so we added lazy loading and preloading as well.

Conclusion:

RouteGuard is used to prevent unauthorized persons to access your web-page. There are five different methods available in AuthGuard which can be used in a different scenario. Preloading is used to speed up navigation. Select the right Preloading strategy according to your requirement and it will help to improve your application performance. Lazy Loading is used to load module on the need to load basis, an unnecessary module that doesn’t come into picture if it is not be loaded until it’s called by user.