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

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.


In typescript it is difficult to know what the function call is especially when you "bind" it. Such as:

HTML

<a id="One"></a> <a id="Two"></a>

and some code creating two objects

let x = new MyClass("I am one", "One");
let y = new MyClass("and I am two", "Two");

with MyClass

class MyClass {
    private _myInstance: string;
    constructor(ID: string, domID: string) {
        this._myInstance = ID;
        document.getElementById(domID).addEventListener('click', this.print.bind(this));
    }

    public print() {
        console.log(this._myInstance);
    }
}

You will correct get "I am one" when clicking on the "One" a element and "and I am two" when clicking on the second a element.

The situation is more difficult with removing. You need to add a object variable that has the binding included so the my class changes to:

class MyClass {
    private _myInstance: string;
    private _myDomID: string;
    private _myFunc = this.print.bind(this);
    constructor(ID: string, domID: string) {
        this._myInstance = ID;
        this._myDomID = domID;
        document.getElementById(domID).addEventListener('click', this._myFunc);
    }

    public print() {
        console.log(this._myInstance);
    }

    public cleanUp() {
        document.getElementById(this._myDomID).removeEventListener('click', this._myFunc);
    }

}


Already answered question, but IMO the answers here are not well designed regarding to OOP. So, here is my solution:

export class MyClass {

  // create member that holds the function reference
  protected clickEventListener: EventListener;      

  // inject the Element
  constructor(protected theElement: Element) {   
    // wrap the class function `onClick` in an arrow function and assign 
    // to the class member `clickEventListener`   
    this.clickEventListener = () => this.onClick(); 
  }

  onClick() {
    console.log("clicked");
  }

  init() {
    // add the event listener to `theElement` and pass only the reference 
    // of `this.clickEventListener` (no round brackets '()')
    this.theElement.addEventListener("click", this.clickEventListener); 
  }

  destroy() {
    // to remve the event listener also just pass the `clickEventListener` reference
    this.theElement.removeEventListener("click", this.clickEventListener); 
  }

}