I encountered an error while setting up my CanDeactivateGuard.
Uncaught (in promise): TypeError: component.canDeactivate is not a function
To ensure reusability, I decided to create a generic version of the CanDeactivateGuard.
For this purpose, I crafted an abstract class called ComponentCanDeactivate and then extended it in the TreeCanDeactivateGuard.
The CanDeactivateGuard should implement the interface CanDeactivate.
Here's a snippet of my code:
import { HostListener } from '@angular/core';
export abstract class ComponentCanDeactivate {
public abstract canDeactivate(): boolean;
@HostListener('window:beforeunload', ['$event'])
unloadNotification($event: any) {
if (!this.canDeactivate()) {
$event.returnValue = true;
}
}
}
The TreeCanDeactivateGuard :
import { ComponentCanDeactivate } from './canDeactivate/component-can-deactivate';
import { NodeService } from '../tree/node.service';
export abstract class TreeCanDeactivateGuard extends ComponentCanDeactivate {
constructor(private _nodeService: NodeService) {
super();
}
public canDeactivate(): boolean {
if (this._nodeService.treeChangesTracer === false) {
return true;
} else {
return false;
}
}
}
The CanDeactivateGuard:
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { ComponentCanDeactivate } from './component-can-deactivate';
@Injectable()
export class CanDeactivateGuard implements CanDeactivate<ComponentCanDeactivate> {
constructor() { }
canDeactivate(component: ComponentCanDeactivate): boolean {
if (!component.canDeactivate()) {
if (confirm('You have unsaved changes! If you leave, your changes will be lost.')) {
return true;
} else {
return false;
}
}
return true;
}
}
Routes Module :
const routes: Routes = [
{
path: '', component: TreeComponent, canDeactivate: [CanDeactivateGuard] , runGuardsAndResolvers: 'always',
}]