Display Material Popup in Angular before user leaves the page

My goal is to display an Angular Material Dialog Box (Popup window) when the user clicks the Chrome Window Close button. The Dialog modal should prompt the user if they want to save changes or cancel.

However, the modal only appears for a brief moment and then closes without waiting for user input. How can I resolve this issue?

How can we detect when the user closes the browser?

@HostListener('window:beforeunload', ['$event'])
beforeunloadHandler(event) {
    this.openDocumentSaveDialog();
}


public openDocumentSaveDialog(): void {
    const documentSaveDialogRef = this.documentSaveDialog.open(DocumentSaveDialogComponent, {
        width: '600px',
        height: '200px',
        disableClose: true,
        autoFocus: false,
        data: null
    });

    documentSaveDialogRef.afterClosed().subscribe(result => {
        this.closeMenu.emit()
    });
}  

https://i.sstatic.net/5U0b1.png

Note: We want to avoid displaying the native Chrome browser popup but instead show a custom popup.

Angular Material Dialog Box: https://material.angular.io/components/dialog

Answer №1

Unfortunately, the beforeunload event does not support a callback function that returns a promise, making it impossible to display a popup and return a value synchronously.

Instead, you can simply always return false or call

event.preventDefault()

If the user chooses to leave the page, you can use

window.close(...)

If not, the event is already canceled.

Your code should be structured like this:

@HostListener('window:beforeunload', ['$event'])
beforeunloadHandler(event) {
    this.openDocumentSaveDialog();
    event.preventDefault();
    event.returnValue = '';
    return false;
}


public openDocumentSaveDialog(): void {
    const documentSaveDialogRef = 
this.documentSaveDialog.open(DocumentSaveDialogComponent, {
        width: '600px',
        height: '200px',
        disableClose: true,
        autoFocus: false,
        data: null
    });

    documentSaveDialogRef.afterClosed().subscribe(result => {
        if(!result)
           window.close()
        this.closeMenu.emit()
    });
}

Answer №2

It is unfortunate that browser security restrictions make it impossible to stop users from closing the window. In my view, there is no way to achieve this; your best option is to display a standard warning message reminding the user about potential data loss upon closing the browser window.

Answer №3

It seems to be effective in my case. However, the lack of control over display is a drawback.

@HostListener('window:beforeunload', ['$event'])
  showWarningMessageOnTabClose($event) {
      $event.returnValue = 'Are you sure you want to leave? Changes may not be saved.';
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating elements in Polymer 2.0 is a breeze. Simply use the `createElement` method, then seamlessly import it using `Polymer

While working on a project, I encountered an issue where I was creating and importing an element while setting attributes with data. The code should only execute if the element hasn't been imported or created previously. However, each time I called th ...

Optimizing jqGrid: Enhancing saveRow function to properly synchronize with editRow function

Exploring how to customize jqGrid's add function for my own needs. I have a navButton with specific requirements: When the user clicks the button, a new row in edit mode should appear on the grid. Once the user enters data and presses enter, the dat ...

Engage with the item provided to an Angular2 component as an Input parameter

In a nutshell, the issue stems from a missing 'this' when referencing the @Input'ed variables. Currently, I have a parent class that will eventually showcase a list of "QuestionComponents". The pertinent section of the parent class templat ...

Issue encountered while defining a component in Angular 16

Currently, I am in the process of learning Angular by following the tutorial provided on Angular.io. As part of this journey, I have declared a home component within my Angular application using the given code: ng generate component home --standalone --in ...

Issue with custom HTML5 video progress bar not syncing with video playback

Currently, I am working on a project using React with Typescript. I have implemented an HTML5 element range for a seek bar in the video player. The issue I am facing is that although the seek bar works correctly when manually dragged, it does not update as ...

Develop an Engaging JavaScript Quiz with Elements That are Generated Dynamically

** Need help setting answer values for checkboxes Currently, I have a code that displays (2) questions with (4) possible answers each. Next to each answer is a checkbox with a default value of false. However, I want to link the value of each checkbox to ...

The class name is not defined for a certain child element in the icon creation function

Currently, I am developing a Vue2 web application using Leaflet and marker-cluster. I am encountering an issue with the iconCreateFunction option in my template: <v-marker-cluster :options="{ iconCreateFunction: iconCreateClsPrg}"> ...

Transmitting data from the front end to the server in React/Shopify for updating API information using a PUT request

After successfully retrieving my API data, I am now tasked with updating it. Within my component, I have the ability to log the data using the following code snippet. In my application, there is an input field where I can enter a new name for my product an ...

Exploring Angular2 utilizing matrix-style URL notation

Which is the preferred method for creating URLs with parameters - using matrix url notation or the traditional ? and & format? I found the explanation in the angular.io documentation confusing. localhost:3000/heroes;id=15;foo=foo or localhost:3000/h ...

What is the best way to display two columns in each row using Angular?

Can you please provide guidance on how to display two columns in each row using Angular? I am attempting to showcase only two columns per row, and if there are more than four items, I want to display them on an ion-slide. Further details will be provided. ...

Conceal dropdown options when there is no text entered

To achieve the functionality of hiding dropdown values when there is no text in the search bar, you can use the following code snippet. The code provided below works perfectly for single selection. However, if you allow multiple value selections, it automa ...

What causes the React app to fail in maintaining the login session with the Node.js server?

Greetings, I have a NodeJS server set up in two separate files: app.js and routes.js. The app.js file includes code for setting up the server, error handling, middleware configuration, and routing logic. The routes.js file contains specific route configu ...

Ways to identify the visible elements on a webpage using JavaScript

I'm working on a nextjs app , I am looking to dynamically update the active button in the navbar based on which section is currently visible on the page. The child elements of the page are structured like this: <div id="section1" > < ...

You cannot assign an optional parameter in Express after it has already been declared

Having trouble with passing optional parameters in my param function as defined below. During testing in Postman, I keep encountering a Reference Error 'off' is not defined. It seems like I'm missing something crucial in how to utilize the p ...

Observes the behavior of a React component with the context.router property being undefined

Currently, I am conducting a test on a react component using chai, karma, and enzyme. mount( <Provider store={configureStore(mockContext, null)}> <Component {...props} /> </Provider> ) In the component, I am utilizing context.router.l ...

How can I make a page scroll to the center when clicking on a carousel?

My goal is to create a webpage where clicking on the carousel will center it on the page. A great example of this functionality can be seen on the Studio New Work website (). As I am still in the process of learning JQuery, I have not yet mastered all the ...

What is the fate of the code that comes after executing history. push in React?

My go-to for routing is typically the Redirect component. It's straightforward since you just need to return the Redirect component when needed. However, I'm a bit lost when it comes to using history objects. In my code base, after pushing a rout ...

accessing the offsetTop property of React elements

When working in React, I've noticed that the offsetTop value of an element differs between componentDidMount and componentDidUpdate. This is surprising to me because I believed componentDidMount occurs after render, meaning the DOM elements should be ...

Implementing a universal (click) attribute for Angular 2 in CSS

When using Angular 1, it was as easy as following this syntax: [ngClick], [data-ng-click], [x-ng-click] { cursor: pointer; } This snippet ensured that any tags with the ng-click attribute displayed a pointer cursor. How can we achieve the same effect ...

"What are the necessary components to include in UserDTO and what is the reasoning behind their

Presenting the User entity: package com.yogesh.juvenilebackend.Model; import jakarta.annotation.Generated; import jakarta.persistence.*; import lombok.*; @Entity @Getter @Setter @NoArgsConstructor @AllArgsConstructor @RequiredArgsConstructor public class ...