Route Guards In Angular
We'll look into Angular Route Guards in this article. CanActivate, CanDeactivate, Resolve, CanLoad, and CanActivateChild are some of the guards that Angular provides. These guards assist us in securing the route or performing certain tasks prior to entering or exiting the route. In this Route Guards article, we'll explore all of these things by creating an example angular guards application.
Angular Route Guards
To regulate whether the user can browse to or away from the current path, we use Angular Guards.
Why Guards
In our Angular Router article, we looked at how to configure our routes and go to different portions of our application. Allowing the user to navigate around the entire application is a bad idea. We need to limit the user until they take particular actions, such as logging in. Route Guards are provided by Angular for this reason.
Authentication is a common circumstance in which Route guards are used. We'd like our app to prevent unauthorized users from accessing the secure route. The CanActivate guard, which angular invokes when the user tries to go inside the protected route, is used to do this. Then we connect to the CanActivate guard and check whether the user is authorized to use the authentication service.
Uses of Angular Route Guards
- To ensure that the navigational operation is working properly.
- Allow select users access to certain areas of the application by asking if they want to save before leaving a view.
- Before going to the route, make sure the specifications are correct.
- Before displaying the component, get some data.
Types of Route Guards
You can use the Angular Router to safeguard the route with five different guards.
- CanActivate
- CanDeactivate
- Resolve
- CanLoad
- CanActivateChild
CanActivate
This guard determines whether or not a route can be activated (or component gets used). When the user is not authorized to navigate to the target component, this protection comes in handy. Alternatively, the user may not be logged into the system.
CanDeactivate
This Guard determines whether the user is allowed to leave the component (navigate away from the current route). This route is handy when the user has outstanding modifications that haven't been saved. Before exiting the component, we can use the CanDeactivate route to ask the user for confirmation. You may ask the user if it's OK to trash rather than save any pending modifications.
Resolve
This protection prevents the route from being activated until certain activities are completed. Before activating the route, you can use the guard to pre-fetch data from the backend API.
CanLoad
The CanLoad Guard prohibits the Lazy Loaded Module from being loaded. This protection is typically used when we don't want an unauthorized user to be able to read the module's source code.
With one exception, this guard works similarly to the CanActivate guard. The CanActivate guard prevents access to a specific route. CanLoad blocks the full lazy loaded module from being downloaded, therefore safeguarding all routes within it.
CanActivateChild
This guard decides whether or not a child route can be used. CanActivateGuard is pretty similar to this guard. This guard is applied to the parent route. When a user tries to go to one of Angular's child routes, this guard is triggered. This allows us to check for certain conditions before deciding whether or not to continue with the navigation.
How to Build Angular Route Guards
The Guards are simple to construct.
- Build the Guard as Service.
- Implement the Guard Method in the Service
- Register the Guard Service in the Root Module
- Update the Routes to use the guards
Build the Guard as Service
The Guard Service is built in the same way as any other Angular Service. Using the Import statement, you must import the matching guard from the Angular Router Library. For example, to use CanActivate Guard, import CanActivate in the import declaration.
import { CanActivate } from '@angular/router';
Then, as shown below, construct a Guard class that implements the selected guard Interface.
@Injectable() export class ProductGuardService implements CanActivate {}
Implement the Guard Method
canActivate(): boolean { // Check weather the route can be activated; return true; // or false if you want to cancel the navigation; }
The return value from the Guard
Register the Guard as Service in Module
providers: [ProductService,ProductGuardService]
Update the Routes
{ path: 'product', component: ProductComponent, canActivate : [ProductGuardService] }
{ path: 'product', component: ProductComponent, canActivate : [ProductGuardService, AnotherProductGuardService ] }
The syntax for adding more guards is the same as well.
{ path: 'product', component, canActivate : any[], canActivateChild: any[], canDeactivate: any[], canLoad: any[], resolve: any[] }
Route guards are executed in the following order:
Angular Guards Example
Guard Service
import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router'; @Injectable() export class ProductGuardService implements CanActivate { constructor(private _router:Router ) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { console.log("canActivate"); //return true //remove comments to return true alert('You are not allowed to view this page. You are redirected to Home Page'); this._router.navigate(["home"]); return false; } }
To begin, we'll need to import the angular/core package's Router, CanActivate, ActivatedRouteSnapshot, and RouterStateSnapshot libraries.
import { Router, CanActivate, ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router';
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { console.log("canActivate"); //return true //remove comments to return true alert('You are not allowed to view this page. You are redirected to Home Page'); //this._router.navigate(["home"]); //navigate to some other route; return false; }
In the Root Module, import the Guard.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { RouterModule } from '@angular/router'; import { AppComponent } from './app.component'; import { HomeComponent} from './home.component'; import { ContactComponent} from './contact.component'; import { ProductComponent} from './product.component'; import { ErrorComponent} from './error.component'; import { ProductDetailComponent} from './product-detail.component'; import { ProductService } from './product.service'; import { ProductGuardService } from './product-guard.service'; import { appRoutes } from './app.routes'; @NgModule({ declarations: [ AppComponent,HomeComponent,ContactComponent, ProductComponent,ErrorComponent, ProductDetailComponent], imports: [ BrowserModule, FormsModule,HttpModule, RouterModule.forRoot(appRoutes)], providers: [ ProductService,ProductGuardService ], bootstrap: [ AppComponent] }) export class AppModule { }
Install the Guard Service first, as indicated below.
import { ProductGuardService } from './product-guard.service';
Then, using the Providers information, register it so that the router may use it. Keep in mind that guards are required at the angular module level.
providers: [ProductService,ProductGuardService],
Update the Routes
import { Routes } from '@angular/router'; import { HomeComponent} from './home.component'; import { ContactComponent} from './contact.component'; import { ProductComponent} from './product.component'; import { ErrorComponent} from './error.component'; import { ProductDetailComponent} from './product-detail.component'; import { ProductGuardService } from './product-guard.service'; export const appRoutes: Routes = [ { path: 'home', component: HomeComponent }, { path: 'contact', component: ContactComponent }, { path: 'product', component: ProductComponent, canActivate :[ProductGuardService] }, { path: 'product/:id', component: ProductDetailComponent }, { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: '**', component: ErrorComponent } ];
We've simply made one change: we've added the ProductGuardService to the CanActivate guard.
{ path: 'product', component: ProductComponent, canActivate : [ProductGuardService] },