The compatibility between Typescript methods and event handlers is lacking

Consider this basic TypeScript script

class foo {
    v: number = 1;

    public bar() {
        console.log(this.v);
    }
}

var a = new foo();
var b = new foo();

document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);

and the HTML

<html lang="en">
<body>
    <button id="test">Test</button>
</body>
</html>

The expected output should be two lines with the number "1".

However, instead of that, I only receive an undefined output.

Upon inspecting the generated JavaScript file

var foo = (function () {
    function foo() {
    this.v = 1;
    }
    foo.prototype.bar = function () {
        console.log(this.v);
    };
    return foo;
}());
var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);
//# sourceMappingURL=Test.js.map

Due to performance reasons, TypeScript places the function on the prototype! Thus, the addEventListener call was essentially adding the prototype (static) function twice as it is the same instance. This explains why I am only receiving one output instead of two.

The main issue arises from the fact that the this keyword within the prototype function refers to the button element which does not contain a property named v!

If we implement this in native JavaScript

var foo = function () {
    this.v = 1;
    var that = this;
    this.bar = function () {
        console.log(that.v);
    }
}

var a = new foo();
var b = new foo();
document.getElementById('test').addEventListener("click", a.bar);
document.getElementById('test').addEventListener("click", b.bar);

We would achieve the desired result!

Is this a known limitation for TypeScript where class methods cannot be used as event handlers?

Furthermore, how can I remove that handler after it has been added?

Answer №1

It's possible. Simply execute this code:

 document.getElementById('trial').addEventListener("click", () => b.foo());

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

Customize RequireJS dependencies for flexible dependency injection

Currently, I am faced with integrating a component that would greatly benefit from Dependency Injection (DI) into an existing framework where DI was not considered during its initial design. The configuration defining dependencies is sourced from a backend ...

Error TS2339: The 'selectpicker' property is not found on the 'JQuery<HTMLElement>' type

Recently, I integrated the amazing bootstrap-select Successfully imported bootstrap-select into my project with the following: <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstra ...

Unable to change the main data of slot object in VueJS

When running this demo and selecting "modify in child", the text will be updated. However, if you choose "modify top level through slot", the text remains unchanged, and attempting to click the other button afterwards will not work. Is there a way to upda ...

Can a JavaScript function be sent back via AJAX from PHP?

Can a javascript function be returned via Ajax from php? Typically, I would just return a value and handle it in plain javascript. However, since I am working on an Apache Cordova mobile app, I need to approach things differently. account = localStorage.g ...

Merge multiple Javascript files into one consolidated file

Organizing Files. /app /components /core /extensions - array.js - string.js /services - logger.js /lib - core.js Core.js (function() { 'use strict'; an ...

Understanding Different Symbols in TypeScript

Can you explain the purpose of symbols in TypeScript to me? As someone familiar with Java, it seems a bit unnecessary to use them alongside an interface declaration. What is the reason for setting symbols in TypeScript? For example, consider the followin ...

Using JavaScript to display a confirmation dialog box with the content retrieved from a text input field

Can a confirm dialog box be used to show the user-entered value from a form's text box? For instance, if the user enters 100.00, I want the dialog box to say something like, "Confirm Amount. Press OK if $100.00 is accurate." ...

Encountering deployment problems with React and TypeScript involving router on Github Pages

After successfully running locally, I encountered a 404 error when deploying the website using "npm run deploy." My application is built with React and TypeScript, utilizing react-router-dom BrowserRouter for navigation between pages. I've spent 7 h ...

Exploring ways to extract key:value pairs from an encoded URL form using POST in express/node.js

I have a web form with 4 input fields. The form is set up as follows: <form action="/" method="post" onsubmit="alert('data submittet')"> It should default to x-www-form-urlencoded. The form functions correctly and I am able to submit my d ...

Can someone guide me on how to personalize a marker icon in Quasar while utilizing Vue2-Leaflet for mapping?

I'm facing an issue with displaying an icon marker image in my Vue2-Leaflet and Quasar project. Instead of the desired image, I am seeing a broken image icon and encountering a 404 error in the console. Despite researching various solutions, I was abl ...

Dynamically Inject HTML with Drag-and-Drop Interaction

Looking for an easy method to move html elements or content around on a webpage? The objective is to drag the element and release it onto a designated area. After dropping the element, customized html content will be added dynamically depending on ...

Ways to eliminate an item in a JSON structure?

Allow me to elaborate. I received a JSON containing numerous objects: data = [{"id":"784","label":"blah","publisher":"me"},{"id":"785","label":"bleh","publisher":"you"},{"id":"786","label":"blih","publisher":"she"}]; For instance, I am looking to elim ...

Issue with MiniCssExtractPlugin during compilation of the entry point build

We have integrated webpack into our deployment process to bundle resources efficiently. However, we are now facing a challenge as we aim to include the bundling of sass files through webpack in order to streamline our build process. The MiniCssExtractPlugi ...

Comparing the differences between while loops and setTimeout function in JavaScript

I'm currently deciding between using a while loop or a setTimeout function in JavaScript. As I understand it, due to JavaScript's single-threaded nature, having one function run for an extended period can hinder the execution of other functions s ...

Conceal the Ajax Div and display the Loader Div while waiting for the data to be

Trying to show a loader div until the Ajax-populated div is returned. Want to hide "responseDiv" until it's filled with Ajax data and display a loading div in the meantime. #loading { background: url('images/loading.gif') no-repeat cent ...

Why does JavaScript often return the constructor of an object instead of false?

Seeking assistance in resolving issues with the functionality of my script. function CatFactory(cat) // Cat constructor { for (y in cats) { if (cats[y].color == cat.color) {return false;} // return false if already in the array ...

Optimal method for identifying all inputs resembling text

I'm in the process of implementing keyboard shortcuts on a webpage, but I seem to be encountering a persistent bug. It is essential that keyboard shortcuts do not get activated while the user is typing in a text-like input field. The approach for hand ...

Has anybody successfully implemented the danfojs-node package on an Apple M1 chip?

I encountered an issue when trying to use danfojs-node on a Mac with an M1 chip - it kept crashing due to TensorFlow. I'm curious if anyone has managed to successfully integrate the npm package from this link (https://www.npmjs.com/package/danfojs-nod ...

Leveraging configuration files for HTML pages without any server-side code

I am currently working on developing an app using phonegap. At the moment, I have the reference to a script in every page like this: <script language="javascript" src="http://someServer/js/myscript.js"></script> If the server 'someServer ...

Youngster listens for guardian's occurrence in Angular 2

While the Angular documentation covers how to listen for child events from parents, my situation is actually the opposite. In my application, I have an 'admin.component' that serves as the layout view for the admin page, including elements such a ...