{{announcement.body}}
{{announcement.title}}

Prevent Users From Losing Unsaved Data

DZone 's Guide to

Prevent Users From Losing Unsaved Data

In this article, we explain how to alert users when they have unsaved data in forms when they try to leave a page in Angular.

· Web Dev Zone ·
Free Resource

There are many instances where a user fills some input in a form, edits that input, and then might attempt to leave the page that they're on. However, often, we'll want to secure the form in such a way that if someone navigates away or closes the browser tab, they should be prompted to confirm that they really want to leave the form with unsaved data.

Whenever these kinds of instances occur, you will see an alert appear on the top of your browser like this:

Leaving page alert
Leaving page alert
Here, we have two different ways of implementing these functionalities:

  • When a user closes or refreshes the tab.
  • When navigation is changed (user clicks back or forward navigation page buttons).

So, let's go ahead with the first implementation:

When a User Closes or Refreshes the Tab

We need to register the window:beforeunload and show a message if the user has unsaved data. The beforeunload event is fired when the window, the document, and its resources are about to be unloaded. The document is still visible, and the event is still cancelable at this point.

This event enables a web page to trigger a confirmation dialog asking the user if they really want to leave the page. If the user confirms, the browser navigates to the new page; otherwise, it cancels the navigation.

For example:
JavaScript




x


 
1
@HostListener('window:beforeunload', ['$event'])
2
public onPageUnload($event: BeforeUnloadEvent) {
3
  if (this.hasUnsavedData()) {
4
    $event.returnValue = true;
5
  }
6
}



2: When the User Navigates to Another Route (Navigation Changed Event):

For the implementation of navigation changed events, you need to initially create a canDeactivate interface. It is an interface that a class can implement to be a guard, deciding if a route can be deactivated. If all guards return true, navigation will continue. If any guard returns false, navigation will be canceled. If any guard returns a UrlTree, current navigation will be canceled and new navigation will be kicked off to the UrlTree returned from the guard.

Initially, we need to write the import statement for canDeactivate , which comes from  '@angular/router'.

JavaScript




xxxxxxxxxx
1


 
1
import { CanDeactivate } from '@angular/router';
2
 
           



Then, we create an interface for the  HasUnsavedData method and import it as well in a guard file/component.
JavaScript




xxxxxxxxxx
1


 
1
export interface HasUnsavedData {
2
  hasUnsavedData(): boolean;
3
}



Add the path to the route config file.
JavaScript




xxxxxxxxxx
1


 
1
{path:'user/new',component:UserFormComponent,canDeactivate: [CanDeactivateGuard]}
2
 
           




Add  CanDeactivate to the ngModule providers. Now, we write the main method to handle this event and showing the popups for displaying the message for unsaved data in the guard file.
JavaScript




xxxxxxxxxx
1
15


 
1
import { Injectable } from '@angular/core';
2
import { CanDeactivate } from '@angular/router';
3
 
           
4
import { HasUnsavedData } from './core.interface';
5
 
           
6
@Injectable()
7
export class HasUnsavedDataGuard implements CanDeactivate {
8
  canDeactivate(component: HasUnsavedData): boolean {
9
    if (component.hasUnsavedData && component.hasUnsavedData()) {
10
      return confirm('You have some unsaved form data.
11
 Are you sure, you want to leave this page?');
12
    }
13
    return true;
14
  }
15
}



We will have to implement the method, CanDeactivate, which gets the component instance and returns true or false. In this example, true will be returned if the message popped up and the user confirmed. Otherwise, the route won't be changed.

Conclusion

To sum up all the blog, as a best practice we should create a generic component to handle any form components. This abstract component will be registered to the browser event and the angular guard will invoke its API: CanDeactivate. It will alert the user that data is unsaved when the form is actually left, not submitted, and dirty.


Further Reading

Topics:
angular ,session ,web dev ,forms ,spa ,javascript

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}