Introduction

The Angular router’s navigation guards allow to grant or remove access to certain parts of the navigation. Another route guard, the CanDeactivate guard, even allows you to prevent a user from accidentally leaving a component with unsaved changes.

Note: Client-side route guards like this are not meant to be a security feature. They won’t prevent a clever user from figuring out a way to get to the protected routes. Such security should be implemented on the server. They are instead meant as a way to improve the user experience (UX) for your apps.

Here are the 4 types of routing guards available:

CanActivate: Controls if a route can be activated.
CanActivateChild: Controls if children of a route can be activated.
CanLoad: Controls if a route can even be loaded. This becomes useful for feature modules that are lazy-loaded. They won’t even load if the guard returns false.
CanDeactivate: Controls if the user can leave a route. Note that this guard doesn’t prevent the user from closing the browser tab or navigating to a different address. It only prevents actions from within the application itself.

Using the CanActivate Route Guard

Route guards are most often implemented as classes that implement the needed route guard interface.
Let’s consider an example with a CanActivate route guard where we ask an auth service if the user is authenticated:
can-activate-route.guard.ts

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

@Injectable()
export class CanActivateRouteGuard implements CanActivate {
  constructor(private auth: AuthService) {}

Notice how we implement the CanActivate interface by declaring a canActivate method. The method optionally has access to the ActivatedRouteSnapshot and the RouterStateSnapshot, in cases where you would need information about the current route.
In our example, the canActivate returns a boolean depending on if the user is authenticated or not, but it could have also returned an observable or a promise that resolve to a boolean.
In order to use them, route guards should be provided like services.
Let’s add it to our app module’s providers:
app.module.ts

// ...
import { AppRoutingModule } from './app-routing.module';
import { CanActivateRouteGuard } from './can-activate-route.guard';

import { AuthService } from './auth.service';

And then lastly, you’ll want to add the guard as part of your routing configuration.
Here an example with a routing module:
app-routing.module.ts

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

import { HomeComponent } from './home.component';
import { DashboardComponent } from './dashboard.component';
import { CanActivateRouteGuard } from './can-activate-route.guard';

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'dashboard',
    component: DashboardComponent,
    canActivate: [CanActivateRouteGuard]
  }
];

Now only users that are authenticated can activate the /dashboard route.
Notice how we provide an array of guards in the route definition. This means that we could specify multiple guards for a single route, and they’ll be evaluated in the order in which they are specified.
Implementing CanLoad and CanActivateChild is accomplished in a similar manner.

Note: The CanLoad interface doesn’t have as much access to the current router state or activated route.

That concludes the example for CanActivate route guards.

Using the CanDeactivate Route Guard

The CanDeactivate guard has a slight difference in its implementation in that we need to provide the component to be deactivated. This allows us to probe the component in question to see if there’s something like unsaved changes.
Let’s consider an example with a CanDeactivate route guard:
can-deactivate-route.guard.ts

import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';

import { DashboardComponent } from './dashboard.component';

In the above example, we assume that there’s a member on the dashboard component class called unsavedChanges that becomes true whenever there are unsaved changes. The route won’t be deactivated unless there are either no unsaved changes or the user confirms.
That concludes the example for CanDeactivate route guards.

Conclusion

In this tutorial, you learned about route guards in Angular like CanActivate and CanDeactivate.
If you’d like to learn more about Angular, check out our Angular topic page for exercises and programming projects.