Is there a way to trigger a request to the backend when the user closes or refreshes the browser?

My Objective:

I am working on a lobby feature that updates automatically when a player leaves. Using backend requests and sockets, the lobby is updated to display the current list of players after someone exits.

The Challenge:

I am faced with the issue of handling situations where a player closes the tab/browser, refreshes the page, or navigates away from the website. Initially, I tried using the beforeunload event to prompt the user before leaving, but was unable to determine if the user chose to leave or stay.

  @HostListener('window:beforeunload', ['$event'])
  unloadNotification($event: any) {
    // Prompt user for confirmation if necessary
    if (!this.canDeactivate()) {
      $event.preventDefault();
      $event.returnValue = true;
    }
    // Ideally, I would like to check the user's action here,
    // but it seems browsers do not allow this capability
    if(userDecidedToLeave){
      this.cleanUp(); // send request to backend to kick player from lobby
    }
  }
}

Eventually, I opted for a simpler approach by utilizing the ngOnDestroy() method. However, I discovered that ngOnDestroy() is not triggered when a user closes the tab/browser, refreshes the page, or navigates elsewhere. This limitation prevents me from sending requests to update the lobby in these scenarios.

  ngOnDestroy() {
    // Check if user has left the lobby
    if (!this.canDeactivate()) {
      this.cleanUp(); // send request to backend to kick user from the lobby and then update lobby
    }
  }

Answer №1

If you are utilizing Web sockets, one way to monitor online users is by checking their status regularly. This approach is particularly useful for the following scenarios:

  • When a user simply refreshes the page, there's no need to display a confirmation dialog or remove them from the chat since they will return shortly.
  • In situations where the user's browser unexpectedly closes (such as a crash or intentional exit on mobile browsers), it is important to keep track of their online presence.

Without relying solely on JavaScript (e.g., using the beforeunload event), achieving this level of functionality may not be feasible.

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

Manage and execute a sequence of multiple actions with Redux-Observable

Utilizing redux-observable, my goal is to generate multiple WORK actions from a single epic. Here's what I have so far: ( action$, state$ ) => { return action$.pipe( ofType( 'SPAWN' ), flatMap( action => { retu ...

There are no versions available for Angular NPM that match [email protected]

Here is the contents of my .npmrc file: registry=https://pkgs.dev.azure.com/<yourOrganization>/_packaging/<yourFeed>/npm/registry/ always-auth=true After deleting node_modules and attempting to install the packages, I encountered the follo ...

The modal functionality in AngularJS doesn't seem to be functioning properly

I am currently working on an Angular application where I want to implement a button that, when clicked, will open a pop-up window displaying a chart. Below is the button code: <div style="padding-top:50px;padding-left:10px;"> <button type="butto ...

What is the best way to transfer a variable from an @Input property to a service within an Angular2 component?

I'm tackling what seems like a simple task, but I'm struggling to figure it out. My issue is this: How can I successfully pass a variable from @Input to a service in an Angular2 component? (Code has been simplified) This is my current component ...

Firestore TimeStamp.fromDate is not based on UTC timing

Does anyone have a solution for persisting UTC Timestamps in Firestore? In my Angular application, when I convert today's date to a Timestamp using the code below, it stores as UTC+2 (due to summer time in Switzerland). import {firebase} from ' ...

I am seeking to modify the CSS of the parent component upon the loading of the child component in Angular

In my Angular blog, I have a root component with a navigation bar containing router links to create a single-page application. My goal is to darken the background around the link when the child component loads. Currently, the link highlights only when pres ...

What is the best way for me to use a ternary operator within this code snippet?

I'm in the process of implementing a ternary operator into this snippet of code, with the intention of adding another component if the condition is false. This method is unfamiliar to me, as I've never utilized a ternary operator within blocks of ...

The VSCode's intellisense for Angular Material fails to function effectively

In the midst of my project on Angular version 13, I have successfully installed Angular Material using the command below: ng add @angular/material The package has been properly included in the node_modules folder. However, when working with TypeScript ...

Why bother with creating mappers to transform entity-to-DTOs?

There are classes referred to as 'mappers' that are utilized by some individuals for converting DTOs to entities or vice versa. What benefits do I stand to gain from employing this technique during backend development? I am keen on delving deepe ...

Tips for effective page management

After creating a navbar in my project, I've come to the realization that it requires a component for each page and subpage. This seems redundant especially when dealing with multiple navigation options like shown in this image. Is it necessary to crea ...

When implementing angular routing, the default route is not automatically selected

When using routerLinkActive for selecting the default route and displaying an image, I encountered an issue where the image was not loading upon initial page load. However, when I switched tabs, the image would display correctly. Below is the code snippet ...

Converting React useState to a JSON object data type

I imported a JSON data file using the following code: import data from "../data.json"; The contents of the file are as follows: [ { "name": "Emery", }, { "name": "Astrid", }, { " ...

Under what circumstances would you need to manually specify the displayName of a React component?

After coming across an article (linked here: https://medium.com/@stevemao/do-not-use-anonymous-functions-to-construct-react-functional-components-c5408ec8f4c7) discussing the drawbacks of creating React components with arrow functions, particularly regardi ...

Angular IVY - The constructor does not match the Angular Dependency Injection format

Encountering an error with 2 services - one being an abstract base service and the other extending it. Here is the error message that I am facing: core.js:3828 ERROR Error: This constructor is not compatible with Angular Dependency Injection because its d ...

I'm eager to showcase live, incoming data on the chart. However, I'm feeling a bit lost on how to proceed. Can you help

I am currently utilizing the line chart feature of ng2-charts in my Angular project. However, I am unsure how to create a graph with real-time data. Here is an example of some sample data being used for the line chart: lineChartData: ChartDataSets[] = [ { ...

Error in Radix UI encountered while attempting to use "react-accordion"

Trying to import the root component of a react accordion and then export it in my project with the name Accordion. However, I keep getting a type error that says Unsafe assignment of an `any` value. I've attempted to fix it by using the as keyword but ...

Reasons Why Optional Chaining is Not Utilized in Transpiling a Node.js + TypeScript Application with Babel

Currently, I am delving into Babel in order to gain a deeper understanding of its functionality. To facilitate this process, I have developed a basic API using Node.js and TypeScript. Upon transpiling the code and initiating the server, everything operates ...

Error in custom TypeScript: Incorrect error instance detected within the component

I encountered a unique issue with my custom Error export class CustomError extends Error{ constructor(message: string) { super(message); Object.setPrototypeOf(this, CustomError.prototype); this.name = "CustomError"; } Furthermore ...

Using TypeScript, you can utilize RxJS to generate a fresh Observable named "Array" from a static array

I've successfully created an observable from an array, but the issue is that its type shows as Observable<number> instead of Observable<number[]> getUsers(ids: string[]): Observable<number[]> { const arraySource = Observable.from ...

Troubleshooting Angular: Investigating why a component is failing to redirect to a different route

I am currently implementing a redirect to a new route upon logging in using the following code: this.router.navigate(['/firstPage']); Oddly enough, when my application is initially loaded, this redirection does not occur automatically after logi ...