Node.js EventEmitter: How to bind a class context to the event listener and then remove this listener
You could do this in the constructor:
this.handleTestEvent = this.handleTestEvent.bind(this);
this.emitter.addListener("test", this.handleTestEvent);
If you want to use cutting edge, you can use the proposed bind operator as a shortcut:
this.handleTestEvent = ::this.handleTestEvent;
this.emitter.addListener("test", this.handleTestEvent);
Or use a property initializer to create a bound method:
constructor(private text: string) {
this.emitter = new EventEmitter();
this.emitter.addListener("test", this.handleTestEvent);
this.emitter.emit("test");
}
handleTestEvent = () => {
console.log(this.text);
}
Related videos on Youtube
![Dominik Palo](https://i.stack.imgur.com/aR9Nc.jpg?s=256&g=1)
Dominik Palo
My interests: Programming (especially mobile apps, Xamarin, .NET C#, WPF and Node.js), 3D printing (RepRap) and open-hardware
Updated on June 13, 2022Comments
-
Dominik Palo about 2 years
Is there a way to access to the class context in the event listener method with possibility to remove the listener?
Example 1:
import {EventEmitter} from "events"; export default class EventsExample1 { private emitter: EventEmitter; constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test", this.handleTestEvent); this.emitter.emit("test"); } public dispose() { this.emitter.removeListener("test", this.handleTestEvent); } private handleTestEvent() { console.log(this.text); } }
In this example removing the listener works, but the
handleTestEvent()
method has no access to the class context usingthis
.this
points to EventEmitter context, sothis.text
is not accessible.Example 2:
import {EventEmitter} from "events"; export default class EventsExample2 { private emitter: EventEmitter; constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test", this.handleTestEvent.bind(this)); this.emitter.emit("test"); } public dispose() { this.emitter.removeListener("test", this.handleTestEvent); } private handleTestEvent() { console.log(this.text); } }
In this example, I'm using the
bind
function to bind a context of the class to the event listener. NowhandleTestEvent
method has access to the class context usingthis
=>this.text
is accessible, but listener cannot be removed withremoveListener
- it seems thatbind
creates a new anonymous function, so there is no reference to the bounded listener.Example 3:
import {EventEmitter} from "events"; export default class EventsExample3 { private emitter: EventEmitter; constructor(private text: string) { this.emitter = new EventEmitter(); this.emitter.addListener("test", () => this.handleTestEvent()); this.emitter.emit("test"); } public dispose() { this.emitter.removeListener("test", this.handleTestEvent); } private handleTestEvent() { console.log(this.text); } }
In this example, I'm using an arrow function to preserve a context of the class in the event listener.
handleTestEvent
method has access to the class context usingthis
, but listener cannot be removed (there is no reference to the bounded listener as in example 2).I've tried an alternative event library - EventEmitter3 which has a support for custom context for events (class context can be passed as third parameter to the
addListener
function (this.emitter.addListener("test", this.handleTestEvent, this
), it works perfectly, but I rather want to use the included EventEmitter from Node.js. -
Alexey Sh. over 3 yearsSyntaxError: Unexpected token =