Angular

Angular form unsaved changes alert before leaving page | Use of Angular canDeactivate guard

Spread the love

What is CanDeactivate Angular?

 

CanDeactivate is a TypeScript interface that needs to be partially implemented in order to create a router. This guard will be used by the route to determine if the route will be closed. Can be applied to any Angular component using the canDeactivate interface.

 

Use case

You can not leave the current page to any route path from any where without save the form if you have unsaved changes data in form on the current page.

 

At first we will create a form in a page and that page route guard by CanDeactivate method. On same page implements a CanDeactivate method that will give you prompt warning for any change in form to save.

 

Follow the below step to complete canDeactivate use case.

 

Step:1

 

Create a canDeactivate guard where CanDeactivate angular interface router method will be implement which return a Boolean value from your component. Next ComponentCanDeactivate interface will implement in your guard component.

 

import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
export interface ComponentCanDeactivate {
  canDeactivate: () => boolean | Observable;
}
@Injectable()
export class unSaveChangeGuard
  implements CanDeactivate
{
  constructor() {}
  canDeactivate(
    component: ComponentCanDeactivate
  ): boolean | Observable {
    return component.canDeactivate();
  }
}

 

Step: 2

 

Implements list of points below

 

  • Implements ComponentCanDeactivate interface
  • Create a reactive form and that form subscribe a subject to track valueChanges of the registration form
  • Use primng dialog service alert to prompt you have a value change.

 

import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Observable, Observer, of, Subject, takeUntil } from 'rxjs';
import { ComponentCanDeactivate } from './guard/un-save-change.guard';
import { HttpService } from './service/http.service';
import { ConfirmationService } from 'primeng/api';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
  selector: 'hello',
  template: `

CanDeactivate Example

`,
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements OnInit, ComponentCanDeactivate, OnDestroy {
  registerForm!: FormGroup;
  submitted = false;
  private hasUnsavedData = false;
  private unsubscribe = new Subject();
  constructor(
    private formBuilder: FormBuilder,
    private _confirmationService: ConfirmationService,
    private _httpService: HttpService
  ) {
    this.registerForm = this.formBuilder.group({
      firstName: new FormControl('', [Validators.required])
    });
  }
  ngOnInit() {
		this.isFormValueChanges();
  }
  get formcontrol() {
		return this.registerForm.controls;
	}
  isFormValueChanges() {
    const form = this.registerForm;
    const initialValue = form.value;
    form.valueChanges.pipe(takeUntil(this.unsubscribe)).subscribe((value) => {
      this.hasUnsavedData = Object.keys(initialValue).some(
        (key) => form.value[key] != initialValue[key]
      );
    });
  }
  onSubmit() {}
  canDeactivate(): Observable | boolean {
    if (this.hasUnsavedData) {
      return new Observable((observer: Observer) => {
        this._confirmationService.confirm({
          message:
            'You have unsaved changes. Do you want to save and leave this page? ',
          accept: () => {
            this.isChanges().subscribe({
              next: (apiResult) => {
                observer.next(true);
                observer.complete();
              },
              error: (apiError) => {
                observer.next(false);
                observer.complete();
              },
            });
          },
          reject: () => {
            observer.next(false);
            observer.complete();
          },
        });
      });
    } else {
      return of(true);
    }
  }
  isChanges() {
    return new Observable((observer: Observer) => {
      this._httpService.fakeApiData().subscribe({
        next: (apiResult) => {
          console.log('fdd',apiResult)
          observer.next(true);
          observer.complete();
        },
        error: (apiError) => {
          observer.next(false);
          observer.complete();
        },
      });
    });
  }
  ngOnDestroy() {
    this.unsubscribe.next();
  }
}

 

Step: 3

 

  • Create a new Component name Welcome Component that link from Hello Component to test Route guard after change value in form.

 

@Component({
  selector: 'hello',
  template: `

CanDeactivate Example


Go to WelcomeComponent`,
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements OnInit, ComponentCanDeactivate, OnDestroy {
  registerForm!: FormGroup;

 

Step: 4

 

Final step add routing path and guard in RouterModule

 

const routes: Routes = [
  {
    path: '',
    redirectTo: 'hello',
    pathMatch: 'full'
  },
  {
    path: 'hello',
    component: HelloComponent,
    canDeactivate: [unSaveChangeGuard]
  },{
    path: 'welcome',
    component: WelcomeComponent
  }
];
@NgModule({
  imports:      [ BrowserModule, FormsModule, ReactiveFormsModule,RouterModule.forRoot(routes),HttpClientModule,ConfirmDialogModule,BrowserAnimationsModule],
  providers: [unSaveChangeGuard,HttpService,ConfirmationService],
  declarations: [ AppComponent, HelloComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

 

Stackblitz Live example

 



 

References

 

Thank you for read this article! Like our Facebook page to get more latest interesting articles update.

 


Spread the love

About Chandra

Technology lover. Professionally Software Developer and write some Technical Blog to help newcomer.
View all posts by Chandra →

2 thoughts on “Angular form unsaved changes alert before leaving page | Use of Angular canDeactivate guard

  1. Heya! I realize this is somewhat off-topic but I needed to ask.
    Does operating a well-established blog such as yours require
    a lot of work? I’m completely new to operating a blog but I do write
    in my journal every day. I’d like to start a blog so I can share
    my personal experience and views online. Please let me know if you have any kind of recommendations or tips for new aspiring blog owners.
    Appreciate it!

    1. At first choose any good hosting as per requirement then your blog category niches. If you want your blog will be more customize and full control then you can go for WordPress else Blogger. In this filed you should have to do keyword research and write SEO friendly content post periodically so that you blog can rank on search engine. There are lot of things in blogging to do after come to this filed one by one you will going to learn and learn there is no end.

Leave a Reply

Your email address will not be published.