javascripttypescriptdom-events

How do you remove an event listener that uses "this" in TypeScript?


In JavaScript, for an event handler that needs access to private members and functions, I can rely on the function scope of those to be accessible within my event handler function, and do something like this:

theElement.addEventListener("click", onClick);

and later:

theElement.removeEventListener("click", onClick);

In TypeScript, I need to use an anonymous function to have this be the containing object, like so:

theElement.addEventListener("click", (event) => this.onClick(event));

In this case, I can't remove the anonymous function from the listening to the event. How do I have an event listener as part of a class (with access to private fields and methods), that I can remove later?


Solution

  • First, JavaScript and TypeScript behave the exact same way even if you write like that:

    theElement.addEventListener("click", onClick);
    

    Second, this is how you can retain a reference to an anonymous function:

    var f = (event) => this.onClick(event);
    theElement.addEventListener("click", f);
    // later
    theElement.removeEventListener("click", f);
    

    If you're dealing with event listeners, there's a useful pattern for your class methods to be bound:

    class MyClass {
        init(theElement) {
            theElement.addEventListener("click", this.onClick);
            theElement.addEventListener("click", this.onClick2);
        }
        print() {
            console.log("print");
        }
        onClick() {
            this.print() // possible error (`this` is not guaranteed to be MyClass)
        }
    
        onClick2 = () => {
            this.print() // no error, `this` is guaranteed to be of type MyClass
        }
    }
    

    Keep in mind, however, that this code will create a separate function onClick2 for every object of class MyClass. That can negatively affect your memory usage, if you create lots of MyClass instances and rarely use their onClick listeners.