Prevent the event listener from continuously triggering

I have a situation where every time I create an Angular component, an event listener is added. However, upon leaving the page and returning to it, a new event listener is added because the constructor is called again.

The problem arises when this event is triggered - it gets invoked multiple times, increasing with each visit back to the page. My intention is for it to be invoked only once.

My framework of choice is Angular14.

Within the constructor (I've also tried using ngOnInit), I have included:

if (window.addEventListener) {
      window.addEventListener('message', this.test.bind(this));
    } 
    else {
      (<any>window).attachEvent('onmessage', this.test.bind(this));
      
    }

Here's my callback function:

test(event: any): void {
    if (event.data !== undefined) {
      if (event.data.msg === 'test') {
      return;
      }  
      if (event.data.msg === 'check') {
        this.dosomething(); 
      
      }
    }
  }

In ngOnDestroy, I attempt to remove the event listener:

ngOnDestroy(): void{
    window.removeEventListener('message', this.test);
    (<any>window).removeEventListener('onmessage', this.test);
  }

Despite these efforts, the issue persists and dosomething is called multiple times on revisiting the component. Any insights or suggestions would be greatly appreciated.

I even tried removing the event listener upon receiving eventdata like so:

 if (event.data.msg === 'check') {
window.removeEventListener('message', this.test);
    (<any>window).removeEventListener('onmessage', this.test);
        this.dosomething(); 
      
      }

Unfortunately, this approach did not work as expected.

Answer №1

When you use the method .bind, a new function is created. To properly remove an event listener, you must provide the exact function that was added earlier. By storing the bound function, you can easily remove it later on.

this.test = this.test.bind(this);
if (window.addEventListener) {
  window.addEventListener('message', this.test);
} else {
  (<any>window).attachEvent('onmessage', this.test);
}
ngOnDestroy(): void {
  window.removeEventListener('message', this.test);
  (<any>window).removeEventListener('onmessage', this.test);
}

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

Tips for arranging various information into a unified column within an Antd Table

Is there a way to display multiple data elements in a single cell of an Ant Design table, as it currently only allows insertion of one data element? I am attempting to combine both the 'transactionType' and 'sourceNo' into a single cell ...

Can one create a set of rest arguments in TypeScript?

Looking for some guidance on working with rest parameters in a constructor. Specifically, I have a scenario where the rest parameter should consist of keys from an object, and I want to ensure that when calling the constructor, only unique keys are passed. ...

Remap Objects Function with Correct Return Data Type

After receiving data from another source via a post request in a large object, I need to extract specific fields and organize them into more precise objects with some fields remapped before inserting them into a database. Currently, I have a working solut ...

Error message: Unable to access property 'post' from undefined - Angular 2

Here is the snippet of code in my component file: import { Component, Injectable, Inject, OnInit, OnDestroy, EventEmitter, Output } from '@angular/core'; import { Http, Response, Headers, RequestOptions } from '@angular/http'; import & ...

Vue 3 - Compelled to utilize any data type with computedRef

Recently, I've been diving into Vue/Typescript and encountered a puzzling error. The issue revolves around a class named UploadableFile: export class UploadableFile { file: File; dimensions: Ref; price: ComputedRef<number>; ... constr ...

Error: the attempt to execute the mongoose connection function has failed due to it not being recognized as a valid function

Hey there, I'm encountering the error TypeError: mongoose__WEBPACK_IMPORTED_MODULE_15___default.a.connect is not a function import mongoose from "mongoose"; const dbURI = 'myurlstuffhere'; mongoose.connect(dbURI , {useNewUrlParser: ...

The modification in Typescript's type order from version 1.7 to 1.8 resulted in a significant

A Visual Studio Cordova application with a unique TypeScript source structure: /src /app /appsub1 appsub1.ts -> 4 : 7 /appsub2 appsub2.ts -> 5 : 6 app.ts -> 3 : 5 /mod1 /mod1sub1 mod1sub1.ts -> 7 : 4 m ...

What could be the reason for the Angular dropdown values not appearing?

Encountering an issue with binding data to a dropdown element, as the dropdown displays NOTHING SELECTED. <select #classProductTypeCombobox name="classProductTypeCombobox" class="form-control col-md-3" [(ngModel)]="classifica ...

Divide MUI theme into individual files

I have encountered an issue in my Next.js project. I currently have an index.ts file residing in the src/theme directory. 'use client'; // necessary for MUI to work with nextjs (SSR) import { createTheme } from '@mui/material/styles'; i ...

Error with constructor argument in NestJS validator

I've been attempting to implement the nest validator following the example in the 'pipes' document (https://docs.nestjs.com/pipes) under the "Object schema validation" section. I'm specifically working with the Joi example, which is fun ...

What is the process for setting up a node test launch configuration?

I have some "node 18 test runner" tests ready to be executed. I can run them using the following command: node --loader tsx --test tests/**/*.ts To debug these tests in vscode, I realized that I need to set up a configuration entry in my launch.json. But ...

Is it possible for Angular to retrieve information from one JSON file but not another?

After updating the names in the code to reflect the current ones, I would greatly appreciate any help or suggestions! The json file has been provided, so there's not much additional setup required. Just a heads up: I haven't created a service fi ...

Executing the Angular 2 foreach loop before the array is modified by another function

Currently, I am facing some difficulties with an array that requires alteration and re-use within a foreach loop. Below is a snippet of the code: this.selectedDepartementen.forEach(element => { this.DepID = element.ID; if (this.USERSDepIDs. ...

Issue encountered while importing supercluster in TypeScript (TypeError: Unable to assign property 'options' to an undefined variable)

After attempting to import supercluster in TypeScript, I encountered the following error. Any helpful insights would be appreciated. ExceptionsManager.js:86 TypeError: Cannot set property 'options' of undefined This error is located at: ...

pressing the button again will yield a new outcome

I am looking to disable a button (material ui) when it is clicked for the second time by setting disabled={true}. Unfortunately, I have not been able to find any examples related to this specific scenario on StackOverflow. <Button onClick={this.s ...

Retrieve: Type 'string | undefined' does not match the parameter type 'RequestInfo'

When using the fetch function, I encountered an error with the "fetchUrl" argument: Error: Argument of type 'string | undefined' is not assignable to parameter of type 'RequestInfo'. This is the code snippet where the error occurred: ...

Problem encountered while directing to a component within Angular

Here is the overview of my directory structure: Directory Structure login.component.ts: import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms ...

Guide to create a React component with passed-in properties

Currently in the process of transitioning a react project from redux to mobx, encountering an issue along the way. Previously, I utilized the container/presenter pattern with redux and the "connect" function: export default connect(mapStateToProps, mapDi ...

Showing container element only if certain condition is met but display the children in Angular 2+

I am looking to create a grid-style view for a list of Angular components, where I can display up to 4 components in each row. The question that comes close to what I need is the following: Angular 2 NgIf, dont render container element on condition but sh ...

Switch between active tabs (Typescript)

I am working with an array of tabs and here is the code snippet: const navTabs: ITab[] = [ { Name: allTab, Icon: 'gs-all', Selected: true }, { Name: sources.corporateResources, Icon: 'gs-resources', Selected: false }, { Name ...