Search code examples
javascriptnode.jseventemitter

Making object instances observable in Node.js


Background

Consider the following:

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

function MyClass() {
  EventEmitter.call(this);
}

util.inherits(MyClass, EventEmitter);

MyClass.prototype = {
  method1: function() {
    this.emit('method1');
  }
}

module.exports = MyClass;

The goal here is to require this module and create instances that are all 'observable' in that their events can pass data to other objects that will handle these events.

I use this module like so:

var MyClass = require('./my-module-index');
var instance = new MyClass();
instance.method1();

Here's the catch:

Calling method1 throws the error:

TypeError: undefined is not a function

whose stack trace points to the emit call.

Question

Should this be a singleton class to have the Observable behavior as implemented or is there something subtle to get instances to emit events that can be handled elsewhere?

I would normally think this was a scoping issue but since the method is on the Object's prototype, this should be referring to any instance (provided new is used).


Solution

  • You're completely blowing away the prototype for MyClass by assigning it to a brand new object so no wonder emit is undefined. Try this instead:

    MyClass.prototype.method1 = function() {
      this.emit('method1');
    };
    

    That should work.

    Here is a good write up on MDN about the prototype chain and how method lookup / inheritance works in JavaScript.