The CanDeactivateFn is a function in Angular that allows you to control whether a route can be deactivated or not. It’s often used to prevent users from navigating away from a page with unsaved changes. In this article, we will see how to implement CanDeactivateFn in Angular15.
Approach- Using a function: canDeactivate: () => boolean
- Using a class: canDeactivate: CanDeactivateFn
Steps to Create an ApplicationStep 1: Install Node.js and npm (if you haven’t already).
npm install -g @angular/cli Step 2: Create a new Angular project
ng new can-deactivate-demo
cd can-deactivate-demo Step 3: Generate the components
ng generate component contact-us
ng generate component welcome
ng generate component register-user Step 4: Install the required modules
ng add @angular/router Project Structure  Folder Structure Dependencies{
"dependencies": {
"@angular/animations": "^15.0.0",
"@angular/common": "^15.0.0",
"@angular/compiler": "^15.0.0",
"@angular/core": "^15.0.0",
"@angular/forms": "^15.0.0",
"@angular/platform-browser": "^15.0.0",
"@angular/platform-browser-dynamic": "^15.0.0",
"@angular/router": "^15.0.0",
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
}
} Approach 1: Using a FunctionYou can implement CanDeactivateFn as a function that returns a boolean value indicating whether the route can be deactivated or not.
HTML
<!--contact-us.component.html-->
<h1>Contact Us</h1>
<button routerLink="/welcome">Welcome</button>
HTML
<!--welcome.component.html-->
<h1>Welcome</h1>
<button routerLink="/register-user"> Register User</button>
HTML
<!--register-user.component.html-->
<h1>Register User</h1>
<button routerLink="/contact-us > Contact Us</button>
JavaScript
//can-deactivate.guard.ts
import { CanDeactivateFn } from '@angular/router';
export const canDeactivateFn: CanDeactivateFn = (component: any) => {
return component.canDeactivate ? component.canDeactivate() : true;
};
JavaScript
//contact-us.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-contact-us',
templateUrl: './contact-us.component.html',
styleUrls: ['./contact-us.component.css']
})
export class ContactUsComponent {
hasUnsavedChanges = true;
canDeactivate(): boolean {
return confirm("Do you want to leave this page? Unsaved changes will be lost.");
}
}
JavaScript
//app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ContactUsComponent } from './contact-us/contact-us.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { RegisterUserComponent } from './register-user/register-user.component';
import { canDeactivateFn } from './can-deactivate.guard';
const routes: Routes = [
{ path: 'contact-us', component: ContactUsComponent, canDeactivate: [canDeactivateFn] },
{ path: 'welcome', component: WelcomeComponent },
{ path: 'register-user', component: RegisterUserComponent },
{ path: '', redirectTo: '/contact-us', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Output How to implement CanDeactivateFn in Angular15 Approach 2: Using a ClassYou can implement CanDeactivateFn as a class that implements the CanDeactivate interface.
HTML
<!--contact-us.component.html-->
<h1>Contact Us</h1>
<button routerLink="/welcome"> Welcome</button>
HTML
<!--welcome.component.html-->
<h1>Welcome</h1>
<button routerLink="/register-user" >Register User</button>
HTML
<!--register-user.component.html-->
<h1>Register User</h1>
<button routerLink="/contact-us"> Contact Us</button>
JavaScript
//app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ContactUsComponent } from './contact-us/contact-us.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { RegisterUserComponent } from './register-user/register-user.component';
import { CanDeactivateGuard } from './can-deactivate.guard';
const routes: Routes = [
{ path: 'contact-us', component: ContactUsComponent, canDeactivate: [CanDeactivateGuard] },
{ path: 'welcome', component: WelcomeComponent },
{ path: 'register-user', component: RegisterUserComponent },
{ path: '', redirectTo: '/contact-us', pathMatch: 'full' }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
JavaScript
//contact-us.component.ts
import { Component } from '@angular/core';
import { CanComponentDeactivate } from '../can-deactivate.guard';
@Component({
selector: 'app-contact-us',
templateUrl: './contact-us.component.html',
styleUrls: ['./contact-us.component.css']
})
export class ContactUsComponent implements CanComponentDeactivate {
canDeactivate(): boolean {
return confirm("Do you want to leave this page? Unsaved changes will be lost.");
}
}
JavaScript
//can-deactivate.guard.ts
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
export interface CanComponentDeactivate {
canDeactivate: () => boolean;
}
@Injectable({
providedIn: 'root',
})
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactivate> {
canDeactivate(component: CanComponentDeactivate): boolean {
return component.canDeactivate ? component.canDeactivate() : true;
}
}
Output How To Implement CanDeactivateFn in Angular15?
|