Add/remove eventListeners while keeping instance context of "this"

I am trying to use the vanilla JS event system to send events between different components of my browser application (no NodeJS involved), by dispatching events to the window object.

// method in Class A
sendDone() {
  window.dispatchEvent(new Event('done');
}

In another class, I have a method which handles the optional listener to this event, which can be enabled/disabled by the user.

// method in Class B
setOption(shouldListen) {
  if (shouldListen) {
    window.addEventListener('done', this.doneHandler);
  } else {
    window.removeEventListener('done', this.doneHandler);
  }
}

However, the handler gets the window context instead of the instance context, and the this keyword doesn't work as I would like it to:

// method in Class B
doneHandler() {
  this.someMethod(this.someValue);  // doesn't work
}

I can't pass this to the handler with an anonymous function, because I can't remove an anonymous function from the listeners list. For the same reason, I can't include the handler code inside the function definition, like this:

const self = this;
window.addEventListener('done', function() {
  // can use self here instead
  // but listener still can't be removed
});

I'm new to JS and I'm wondering how this sort of scenario is usually handled.

Thanks.

1 answer

  • answered 2021-09-23 09:33 Danziger

    You need to use Function.prototype.bind() in the constructor of your class:

    constructor() {
        this.doneHandler = this.doneHandler.bind(this);
    }
    

    The rest of the code won't change, so now you can add and remove the event listener.

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum