Welcome to our comprehensive guide on Angular's CanDeactivate Guard! In this lesson, we'll delve into this powerful feature, explaining its purpose, importance, and practical usage.
The CanDeactivate Guard is a mechanism in Angular that allows you to prevent a component from navigating away until certain conditions are met. This is particularly useful when you have a form with unsaved changes and you want to ensure that the user confirms they want to leave.
Say goodbye to annoying pop-ups asking if you're sure you want to leave a form with unsaved changes! CanDeactivate Guard lets you implement this functionality elegantly and seamlessly, enhancing the user experience of your Angular applications.
To implement a CanDeactivate Guard, follow these steps:
ng generate service canDeactivatecanDeactivate method in the service.import { Observable, of } from 'rxjs';
import { CanDeactivate } from '@angular/router';
export class CanDeactivateGuard implements CanDeactivate<any> {
canDeactivate(component: any): Observable<boolean> | Promise<boolean> | boolean {
if (component.form.dirty) {
return confirm('You have unsaved changes. Are you sure you want to leave?');
}
return true;
}
}import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FormComponent } from './form.component';
import { CanDeactivateGuard } from './can-deactivate.guard';
const routes: Routes = [
{ path: '', component: FormComponent, canDeactivate: [CanDeactivateGuard] },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class FormRoutingModule {}Let's take a look at a more complex example where we have a FormComponent with multiple tabs, and we want to implement CanDeactivate Guard for each tab.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { CanDeactivateGuard } from './can-deactivate.guard';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.css'],
})
export class FormComponent {
form: FormGroup;
constructor(private fb: FormBuilder, private route: ActivatedRoute, private router: Router) {
this.form = this.fb.group({
tab1: ['', Validators.required],
tab2: ['', Validators.required],
});
}
navigate(route: string) {
this.router.navigate([route]);
}
}In this example, we have a FormComponent with two tabs, each having a form with required fields. We'll implement the CanDeactivate Guard for both tabs.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { CanDeactivateGuard } from './can-deactivate.guard';
export class Tab1Component {
form: FormGroup;
constructor(private fb: FormBuilder, private route: ActivatedRoute, private router: Router) {
this.form = this.fb.group({
tab1: ['', Validators.required],
});
}
navigate() {
this.router.navigate(['..'], { relativeTo: this.route });
}
}
export class Tab2Component {
form: FormGroup;
constructor(private fb: FormBuilder, private route: ActivatedRoute, private router: Router) {
this.form = this.fb.group({
tab2: ['', Validators.required],
});
}
navigate() {
this.router.navigate(['..'], { relativeTo: this.route });
}
}Finally, we update our CanDeactivate Guard to handle the tabs:
import { Component } from '@angular/core';
import { CanDeactivate } from '@angular/router';
import { Observable, of } from 'rxjs';
export class CanDeactivateGuard implements CanDeactivate<any> {
canDeactivate(component: any): Observable<boolean> | Promise<boolean> | boolean {
if (component instanceof Tab1Component && component.form.dirty) {
return confirm('You have unsaved changes in Tab 1. Are you sure you want to leave?');
}
if (component instanceof Tab2Component && component.form.dirty) {
return confirm('You have unsaved changes in Tab 2. Are you sure you want to leave?');
}
return true;
}
}Now, when the user navigates away from the form, Angular will check if any of the tabs have unsaved changes and prompt the user accordingly.
What does the `CanDeactivate` Guard do in Angular?