Search code examples
node.jsprototypeecmascript-5eventemitter

Extending Node's EventEmitter in ES5


I'm learning JavaScript/Nodejs and I've decided to start with ES5 before looking at ES6. I'm looking at prototypical inheritance and the EventEmitter.

I want to extend EventEmitter with something simple, my code sample is below. However I receive the error:

this.emit('messageRead', message);

TypeError: this.emit is not a function

What am I doing wrong?

var EventEmitter = require('events').EventEmitter;

var MyEmitter = function() {
    EventEmitter.call(this);
    this.messages = []
}

MyEmitter.prototype = Object.create(EventEmitter.prototype);
MyEmitter.prototype.constructor = MyEmitter;
MyEmitter.prototype.addMessage = function(message) {
    this.messages.push(message)
    this.emit('messageAdded', message);
    return this;
}
MyEmitter.prototype.readMessages = function() {
    this.messages.forEach(function(message){
        this.emit('messageRead', message);
    });
    return this;
}

var emitter1 = new MyEmitter();
emitter1
    .addMessage('hello')
    .addMessage('goodbye')
    .on('messageAdded', function(message) { console.log('message added: ' + message)})
    .on('messageRead', function(message) { console.log('message read: ' + message)})
    .readMessages();

Solution

  • The issue with my code was with this and closures. See the updated readMessages below.

    But thanks to @Yarsolav who has probably pointed at a better solution.

    var EventEmitter = require('events').EventEmitter;
    
    var MyEmitter = function() {
        EventEmitter.call(this);
        this.messages = []
    }
    
    MyEmitter.prototype = Object.create(EventEmitter.prototype);
    MyEmitter.prototype.constructor = MyEmitter;
    MyEmitter.prototype.addMessage = function(message) {
        this.messages.push(message)
        this.emit('messageAdded', message);
        return this;
    }
    MyEmitter.prototype.readMessages = function() {
        var that = this;
        this.messages.forEach(function(message){
            that.emit('messageRead', message);
        });
        return this;
    }
    
    var emitter1 = new MyEmitter();
    emitter1
        .on('messageAdded', function(message) { console.log('message added: ' + message)})
        .on('messageRead', function(message) { console.log('message read: ' + message)})
        .addMessage('hello')
        .addMessage('goodbye')
        .readMessages();