Search code examples
angulardebuggingonbeforeunload

How can I use @HostListener('window:beforeunload') to cancel routing?


I try to call the confirm before my component is unloaded, but it doesn't work.

I call confirmation by click, and in the case when I receive a false, the routing still occurs.

Probably, am I missing something?

import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';

Component({
    templateUrl: 'some-component.html',
    styleUrls: ['./some-component.scss']
})

export class SomeComponent implements OnInit, OnDestroy {
    public ifAllowed: boolean = false

    @HostListener('window:beforeunload')
    onBeforeUnload(event) {
        this.checkValue()
    }

    ngOnDestroy() {
        this.checkValue()
    }

    checkValue() {
        if(!ifAllowed) {
            let isContinue = confirm('Any unsaved data will be lost. Сontinue?')
            if (!isContinue) {
                return false  // not working
            }
        }
    }
}


Solution

  • If someone comes in handy, a solution is found.

    For beforeunload:

    @HostListener('window:beforeunload', ['$event'])
    onbeforeunload(event) {
      if (!ifAllowed) {
        event.preventDefault();
        event.returnValue = false;
      }
    }
    

    When checking for component changes: create a guard

    import {Injectable} from '@angular/core';
    import {CanDeactivate} from '@angular/router';
    
    @Injectable()
    export class ConfirmationGuard implements CanDeactivate<any> {
    
      constructor() {}
    
      canDeactivate(component: any): boolean {
        if (component.ifAllowed) {
          return confirm('Are you sure?');
        }
        return true;
      }
    }
    

    Do not forget to register a guard in providers:

    providers: [
      ConfirmationGuard
    ]
    

    and in the routing module for the necessary path add canDeactivate method:

    canDeactivate: [ConfirmationGuard]