Open In App

How To Implement CanDeactivateFn in Angular15?

Last Updated : 12 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

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 Application

Step 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

Capture
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 Function

You 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

Angular-CanDeactivate-Guard-Example
How to implement CanDeactivateFn in Angular15

Approach 2: Using a Class

You 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

Angular-CanDeactivate-Guard-Example
How To Implement CanDeactivateFn in Angular15?

Next Article

Similar Reads