onbeforeunload confirm dialog not showing when angular2 @HostListener is used
Asked Answered
Q

5

18

Using @HostListener hook, but confirm dialog (that asks: Do you want to Leave this page? ...or Do you want to Reload this page?) is not showing.

The code works, but the confirm dialog is not showing.

Here what I have:

@HostListener('window:beforeunload', ['$event'])
public doSomething($event) {
    console.log("do I see this?") // <---- this logs to the console.

    return "something else";
}

But I don't see this:

enter image description here

Quickel answered 23/3, 2017 at 20:57 Comment(4)
Look into candeactivate for this I thinkDiedra
I guess this is because Angular bindings modify the returned value. If you return true, it is used as preventDefault(). I assume your code returning a string will not behave like you expect or like beforeunload requires. Just use window.addEventListener(...) instead.Duramen
thanks @GünterZöchbauer if I return false, it works as expected. But, as you said, it's quite possible the angular bindings modify the return value.Quickel
How to capture Leave, Stay eventsBukhara
Q
19

returning false instead of the string "something else" fixes the problem and the confirm dialog is shown.

It's quite possible that Angular bindings modify the return value

Quickel answered 24/3, 2017 at 15:59 Comment(0)
S
10

For anybody still looking for another way to handle this in Angular. You can try doing this:

<router-outlet (window:beforeunload)="doBeforeUnload()" (window:unload)="doUnload()"></router-outlet>

Here I added the events to an event router-outlet bucause its the only thing in my app.component.html but you can add it to a container or wrapper. Also added both events because one beforeunload will only show the alert to the user when returning false and then unload handles the actual closing event. This is important because you may want to know what to do when the user continues or actually decides to close or handling unwanted clicks. The actual functions look like this:

doBeforeUnload() {
    // Alert the user window is closing 
    return false;
}

doUnload() {
    // Clear session or do something
    this.auth.getLogout();
}

PD: I tested this in Angular 6.

Streamlet answered 3/7, 2018 at 0:1 Comment(1)
This was the only solution that worked for me (on Angular 5). I had a working canDeactivate guard which checked for changes before allowing the user to leave the page but it didn't work when trying to do a page refresh or when closing the browser - this works for both (using only beforeunload). My problem is that other solutions using HostListener would always fire and prompt the user (if the function contained false and irregardless of whether something had changed on the page) or not fire at all (if the function contained true). Maybe it depends on your environment?Seidler
C
7

Instead of returning false you need to return $event.returnValue = "your text"

Modern browsers does not show your entered text.

@HostListener('window:beforeunload', ['$event']) 
yourfunction($event) {
    return $event.returnValue='Your changes will not be saved';
}
Chimerical answered 12/9, 2017 at 3:59 Comment(0)
F
1

You need to return this

return $event.returnValue = "something";

However, in modern browsers, the message you set will not show. The browsers will simply show their browser defaults

Farrago answered 5/4, 2017 at 17:15 Comment(0)
F
1

Be aware that beforeunload and unload event listeners both have side effects in case you are planning to use bfcache (back/forward cache) in your Angular application. So use with caution. Read here: https://web.dev/bfcache/#only-add-beforeunload-listeners-conditionally

Forepeak answered 28/5, 2022 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.