Route Guards with canActivate and canDeactivate in Angular
📖 Scenario: You are building a simple Angular app with two pages: a Dashboard and a Profile. You want to protect the Dashboard so only logged-in users can access it. Also, when users try to leave the Profile page with unsaved changes, you want to warn them before they leave.
🎯 Goal: Build route guards using canActivate to protect the Dashboard route and canDeactivate to warn users about unsaved changes on the Profile page.
📋 What You'll Learn
Create a boolean variable isLoggedIn to simulate user login status
Create a canActivate guard that allows navigation only if isLoggedIn is true
Create a canDeactivate guard that asks for confirmation if there are unsaved changes
Apply these guards to the Angular routes for Dashboard and Profile respectively
💡 Why This Matters
🌍 Real World
Route guards are used in real apps to protect pages from unauthorized access and prevent data loss by warning users before leaving pages with unsaved changes.
💼 Career
Understanding route guards is essential for Angular developers to build secure and user-friendly web applications.
Progress0 / 4 steps
1
Set up the login status variable
Create a boolean variable called isLoggedIn in the auth.service.ts file and set it to false to represent the user not logged in.
Angular
Hint
Think of isLoggedIn as a simple switch that tells if the user is logged in or not.
2
Create the canActivate guard
In auth.guard.ts, create a class AuthGuard that implements CanActivate. Add a method canActivate() that returns this.authService.isLoggedIn. Inject AuthService in the constructor.
Angular
Hint
Remember to inject AuthService in the guard's constructor to access isLoggedIn.
3
Create the canDeactivate guard
Create a CanComponentDeactivate interface with a method canDeactivate() that returns boolean or Promise<boolean>. Then create a PendingChangesGuard class implementing CanDeactivate<CanComponentDeactivate>. In canDeactivate(), call the component's canDeactivate() method. Inject nothing.
Angular
Hint
The guard calls the component's canDeactivate() method to check if navigation away is allowed.
4
Apply guards to routes
In app-routing.module.ts, add routes for DashboardComponent and ProfileComponent. Protect the Dashboard route with canActivate: [AuthGuard]. Protect the Profile route with canDeactivate: [PendingChangesGuard]. Import the guards and components properly.
Angular
Hint
Use canActivate and canDeactivate arrays in the route definitions to apply the guards.
Practice
(1/5)
1. What is the primary purpose of the canActivate guard in Angular routing?
easy
A. To handle errors during route navigation.
B. To check if navigation to a route is allowed before entering it.
C. To preload data before the route loads.
D. To confirm if navigation away from a route is allowed.
Solution
Step 1: Understand the role of canActivate
canActivate is a route guard that runs before entering a route to decide if navigation is allowed.
Step 2: Differentiate from other guards
canDeactivate checks leaving a route, not entering. Preloading and error handling are unrelated to canActivate.
Final Answer:
To check if navigation to a route is allowed before entering it. -> Option B
Hint: Use canDeactivate: [Guard] to protect leaving a route [OK]
Common Mistakes:
Using canActivate instead of canDeactivate for leaving routes
Confusing canLoad with canDeactivate
Missing brackets around guard name
3. Given this canDeactivate guard code snippet, what will happen when the user tries to leave the EditComponent with unsaved changes?
export class UnsavedChangesGuard implements CanDeactivate<EditComponent> {
canDeactivate(component: EditComponent): boolean {
if (component.hasUnsavedChanges()) {
return confirm('You have unsaved changes. Leave anyway?');
}
return true;
}
}
medium
A. The guard throws an error because confirm is not allowed.
B. The user is always allowed to leave without confirmation.
C. The user is blocked from leaving if there are unsaved changes.
D. The user is asked to confirm leaving only if there are unsaved changes.
Solution
Step 1: Analyze the guard logic
The guard checks if component.hasUnsavedChanges() returns true, then asks for confirmation.
Step 2: Understand the confirm behavior
If the user confirms, confirm() returns true allowing navigation; otherwise, navigation is blocked.
Final Answer:
The user is asked to confirm leaving only if there are unsaved changes. -> Option D
Quick Check:
canDeactivate confirms only if unsaved changes exist [OK]
Hint: canDeactivate can prompt user to confirm leaving [OK]
Common Mistakes:
Assuming user can leave without confirmation always
Thinking guard blocks leaving without prompt
Believing confirm causes errors in Angular guards
4. Identify the error in this canActivate guard implementation:
export class AuthGuard implements CanActivate {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
if (this.authService.isLoggedIn()) {
return true;
}
}
}
medium
A. Missing return statement when user is not logged in.
B. Incorrect method name; should be canDeactivate.
C. The guard should return a Promise, not boolean.
D. The guard must not use services inside canActivate.
Solution
Step 1: Check all code paths return a value
If isLoggedIn() is false, the method returns nothing (undefined), which is invalid.
Step 2: Understand guard return requirements
canActivate must return true, false, or an observable/promise resolving to those. Missing return causes errors.
Final Answer:
Missing return statement when user is not logged in. -> Option A
Quick Check:
All canActivate paths must return true/false [OK]
Hint: Always return true or false in all canActivate paths [OK]
Common Mistakes:
Not returning false or redirect when unauthorized
Confusing canActivate with canDeactivate method names
Thinking services can't be used in guards
5. You want to prevent users from leaving a form page if they have unsaved changes, but only if they are editing (not creating new). Which approach correctly uses canDeactivate to achieve this?
hard
A. Use canActivate guard to check unsaved changes before entering the form route.
B. Use canDeactivate guard that always returns true to allow navigation.
C. Use canDeactivate guard that checks component.isEditing and component.hasUnsavedChanges() before confirming navigation.
D. Use canActivateChild guard to block leaving the form.
Solution
Step 1: Identify when to block navigation away
Blocking leaving only applies when editing and unsaved changes exist, so guard must check both conditions.
Step 2: Use canDeactivate guard properly
canDeactivate runs when leaving a route, so it is the correct place to check and confirm navigation.
Final Answer:
Use canDeactivate guard that checks component.isEditing and component.hasUnsavedChanges() before confirming navigation. -> Option C
Quick Check:
canDeactivate with condition on editing and unsaved changes [OK]
Hint: Check editing and unsaved changes inside canDeactivate guard [OK]
Common Mistakes:
Using canActivate to block leaving routes
Always returning true in canDeactivate guard
Confusing canActivateChild with canDeactivate
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.