shakell
shakell

Reputation: 351

angular - showing alert when user leaves one page (one component)

Expected behavior

I have one page which contains one form, when the user want to leave this page, actually it is just one component, I want show some alert like "Do you really want to leave this page? Your changes will not be saved".

Currently behavior

I have tried

@HostListener('window:beforeunload', ['$event']) yourfunction($event) {
  return $event.returnValue='Your changes will not be saved';
}

But the dialogue didn't appear.

Any ideas or suggestions will be welcomed.

Upvotes: 1

Views: 1508

Answers (2)

Siddharth Jain
Siddharth Jain

Reputation: 336

You can use canDeactivate as i used in my application
below example

     @Injectable()
export class RouteLinkGuard implements CanDeactivate<Componentchanged> {
  constructor(private router: Router, private confirmationService: ConfirmationService, private commonService: CommonService) {}

  canDeactivate(Componentchanged: Componentchanged) {
// Here you can use whatever logic you want 
    if (this.commonService.getChangedValue() === true) {
      return Observable.create((observer: Observer<boolean>) => {
        this.confirmationService.confirm({
          message: 'Are you sure you want to leave this page? Any unsaved data would be lost?',
          header: 'Not saved',
          icon: 'fa fa-info',
          accept: () => {
            observer.next(true);
            observer.complete();
          },
          reject: () => {
            observer.next(false);
            observer.complete();
          }
        });
      });
    } else {
      return true;
    }
  }
}

//In Module
// You is like below
const routes: Routes = [
  {
    path: '',
    component: Componentchanged,
    canDeactivate: [RouteLinkGuard]
  }
];

Upvotes: 0

Armen Vardanyan
Armen Vardanyan

Reputation: 3315

This is because in Angular the transition between pages is not a "real" one, and the window.beforeunload event does not fire. To manage this, you have to use Angular's own Router Guards, specifically a canDeactivate one. Here is a link to the specific doc about the canDeactivate guard. Your actual code may look something like this:

@Injectable()
class DeactivateGuard implements CanDeactivate<YourComponent> {
    canDeactivate(){
//your popup logic goes here. Note that this method should return 
// a boolean, or a Promise/Observable of a boolean, if any async operations are present
   }
}

After you create this guard, you just have to place it on your route definition:

{path: 'path-to-your-component', component: YourComponent, canDeactivate: [DeactivateGuard]}

Upvotes: 1

Related Questions