In Angular, a guard is essentially a powerful tool used to control access to different parts of your application based on certain conditions.
A guard is a script that runs before certain stages of route navigation. It acts as an intermediary, deciding whether the navigation process should be allowed to continue to the requested route or be stopped/redirected. Think of them like bouncers at a club, checking if you meet the criteria to enter.
Why Use Angular Guards?
Guards are crucial for implementing logic that determines if a user can access a specific route. Common use cases include:
- Authentication: Preventing unauthenticated users from accessing protected areas.
- Authorization: Ensuring a user has the necessary permissions (e.g., admin rights) to view a specific page.
- Data Loading: Making sure necessary data is loaded before rendering a component.
- User Confirmation: Prompting a user before they navigate away from a page with unsaved changes.
How Guards Work
When a user attempts to navigate to a route that has a guard associated with it, Angular executes the guard's logic before the navigation completes. The guard then returns a value (typically true
, false
, a UrlTree
, or an Observable
/Promise
resolving to one of these) that tells Angular how to proceed:
true
: Proceed with the navigation.false
: Cancel the navigation.UrlTree
: Cancel the navigation and redirect to the specified URL.
Primary Types of Guards
Angular provides several types of guards, each designed for a specific stage of the navigation lifecycle. According to the reference provided, The primary types of guards in Angular are: CanActivate.
Here's a brief look at some key guard types:
Guard Type | Purpose | When it Runs |
---|---|---|
CanActivate |
Decides if a route can be activated. | Before navigating to the route. |
CanActivateChild |
Decides if child routes within a parent route can be activated. | Before navigating to any child route. |
CanDeactivate |
Decides if a user can leave the current route. | Before navigating away from the route. |
Resolve |
Fetches data before the route is activated. | Before activating the route. |
CanLoad |
Decides if a lazy-loaded module can be loaded. | Before loading the module for a lazy-loaded route. |
As highlighted by the reference, CanActivate
is one of the most commonly used guards, often employed for authentication checks.
Implementing a Guard (Example: CanActivate)
Implementing a guard involves creating a class that implements the relevant guard interface (e.g., CanActivate
) and provides the required method (e.g., canActivate
).
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service'; // Assuming you have an AuthService
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.authService.isAuthenticated()) {
return true; // User is logged in, allow access
} else {
// User is not logged in, redirect to login page
return this.router.createUrlTree(['/login']);
}
}
}
You then apply this guard to a route configuration in your Angular routing module:
import { Routes } from '@angular/router';
import { DashboardComponent } from './dashboard/dashboard.component';
import { LoginComponent } from './login/login.component';
import { AuthGuard } from './auth.guard';
export const routes: Routes = [
{ path: 'login', component: LoginComponent },
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard] // Apply the guard here
},
// ... other routes
];
With this setup, the AuthGuard
's canActivate
method will run every time a user tries to navigate to the /dashboard
route, ensuring only authenticated users can access it.
Guards are a fundamental part of building robust and secure Angular applications by providing fine-grained control over the navigation flow.