Search code examples
node.jsecmascript-6eventemitteres6-class

Connect event emitter with instance of each ES6 class in node


I'm trying to associate each instance of a class with an event emitter. I'm trying the following:

const events = require("events");
const eventEmitter = new events.EventEmitter();

class Camera {
    constructor(ip) {
        this.ip = ip;

        eventEmitter.on("recordVideo", function() {
            this.recordClip();
        });
    }

    recordClip() {
        console.log("record " + this.ip);
    }
}

var cam = new Camera("0.0.0.0");
eventEmitter.emit("recordVideo");

But I get back:

TypeError: this.recordClip is not a function

How can I have each instance of my class listen for the event?


Solution

  • Your issue here is that this is in the context of the event emitter, not the class. So, eventEmitter does not have recordClip as a method. You need to either lexically bind your callback with an arrow function:

    (Personally, I think this is the best, and most modern/readable way to do this)

    eventEmitter.on("recordVideo", () => {
        this.recordClip();
    });
    

    Or, you need to bind the proper scope:

    eventEmitter.on("recordVideo", function() {
        this.recordClip();
    }).bind(this);
    

    Or you can make a reference to this via the self methodology:

    class Camera {
        constructor(ip) {
            this.ip = ip;
            const self = this; //assign this to self
            eventEmitter.on("recordVideo", function() {
                self.recordClip(); //use self, not this here
            });
        }
    
        recordClip() {
            console.log("record " + this.ip);
        }
    }