What are route guards in Angular and what types exist?
Learn Angular route guards — CanActivate, CanDeactivate, CanMatch and resolvers — with functional guard examples to control and secure navigation in your app.
Expected Interview Answer
Route guards are interfaces the Angular Router calls to decide whether navigation to, away from, or the loading of a route is allowed. They return a boolean, a UrlTree, or an Observable/Promise of either to permit, block, or redirect navigation.
In modern Angular they are plain functions (functional guards) that use inject() to access services, replacing the older class-based guard interfaces. The main types are CanActivate (enter a route), CanActivateChild (enter child routes), CanDeactivate (leave a route, e.g. unsaved-changes prompts), CanMatch (whether a route configuration matches at all, useful for feature flags and lazy modules), and the resolver resolve function for pre-fetching data. Guards run in a defined order and any guard returning false or a UrlTree cancels or redirects the navigation.
- Centralizes authorization and access-control logic
- Prevents users from reaching unauthorized or invalid routes
- Protects against data loss with CanDeactivate confirmation prompts
- Enables conditional lazy loading with CanMatch
- Keeps components focused on rendering, not permission checks
AI Mentor Explanation
A route guard is like the third umpire reviewing a decision before play continues: the on-field call (navigation request) is paused, the umpire checks the evidence (auth token, unsaved state) and either signals out, not-out, or asks for a fresh delivery, and only then does the match proceed to the next ball.
Step-by-Step Explanation
Step 1
Create a functional guard
Write a function typed as CanActivateFn (or the relevant guard type) that uses inject() to pull in services like AuthService and Router.
Step 2
Implement the check
Return true to allow, false to block, or a UrlTree (via router.createUrlTree / parseUrl) to redirect the user elsewhere.
Step 3
Attach it to a route
Add the guard to the route's canActivate, canDeactivate, canMatch, or resolve property in the Routes configuration.
Step 4
Handle async results
Return an Observable or Promise when the decision depends on an HTTP call or store selector; the router waits for it to resolve.
Step 5
Order and combine
Understand that CanMatch runs first, then CanActivate/CanActivateChild, and CanDeactivate runs when leaving; a single false anywhere cancels the navigation.
What Interviewer Expects
- Knowledge of the different guard types and when each applies
- Awareness that modern Angular uses functional guards with inject()
- Understanding that guards can return UrlTree to redirect
- Explanation of CanDeactivate for unsaved-changes protection
- Grasp of async guards returning Observable/Promise
Common Mistakes
- Believing guards enforce real security instead of server-side authorization
- Returning false when a redirect via UrlTree is actually intended
- Confusing CanMatch with CanActivate for lazy-loaded routes
- Forgetting that class-based guards are deprecated in favor of functions
- Not handling the async case, causing navigation to proceed prematurely
Best Answer (HR Friendly)
“Route guards are checkpoints in an Angular app that decide whether a user is allowed to open, leave, or load a particular page. For example, they can block someone who isn't logged in or warn a user before they leave a form with unsaved changes.”
Code Example
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';
export const authGuard: CanActivateFn = (route, state) => {
const auth = inject(AuthService);
const router = inject(Router);
if (auth.isLoggedIn()) {
return true;
}
// Redirect to login, preserving the attempted URL
return router.createUrlTree(['/login'], {
queryParams: { returnUrl: state.url },
});
};
// In routes:
// { path: 'dashboard', component: DashboardComponent, canActivate: [authGuard] }Follow-up Questions
- How does CanMatch differ from CanActivate for lazy-loaded routes?
- How would you implement an unsaved-changes prompt with CanDeactivate?
- Why are functional guards preferred over class-based guards now?
- How do you return a redirect from a guard?
- In what order do multiple guards execute during navigation?
MCQ Practice
1. Which guard is best for warning users about unsaved form changes before leaving a page?
CanDeactivate runs when the user attempts to navigate away, making it ideal for confirming loss of unsaved changes.
2. What can a guard return to redirect the user instead of just blocking navigation?
Returning a UrlTree tells the router to cancel the current navigation and navigate to that URL instead.
3. Which guard type decides whether a route configuration matches at all, useful for feature flags?
CanMatch runs before the route is matched, so it can prevent a lazy-loaded route from even being considered.
Flash Cards
What does a route guard return? — A boolean, a UrlTree, or an Observable/Promise of either — to allow, block, or redirect navigation.
Which guard protects unsaved changes? — CanDeactivate, which runs when navigating away from the current route.
What replaced class-based guards? — Functional guards — plain functions using inject() to access services.
What is CanMatch for? — Deciding whether a route (often lazy-loaded) matches at all, enabling feature flags and conditional loading.