Search code examples
javascriptnode.jseventemitter

Integrate EventEmitter in Object construtor to use in prototype methods


I have the following, strange problem: I wrote a "Class" Game. This Class has a constructor and one prototype method. I want the whole construct to be an EventEmitter. So I thought I could just inherit the event.EventEmitter for my constructor. It looked first as follows:

game.js

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

/*
  Game factory
*/

function Game(catalogue, speed) {

  //EventEmitter.call(this);

  this.catalogue  = catalogue || null;
  this.speed      = speed || 10;  

}

Game.prototype.listen = function(){
  var self = this;
  setInterval(function(){
    self.emit('init', 0);
  }, 500);
}

util.inherits(Game, EventEmitter);
module.exports = Game;

I use socket.io to connect to the client. In my main socket routine I use the following code to start a new game (instantiate)

controller.js

socket.on('startGame', function(){      

  var myGame = new Game('default', 10);
  myGame.init();

  myGame.on('init', function(status){
    console.log('Did start with status code: ', status);
  });
};

This does not work as expected.Error is:

Missing error handler on `socket`.
TypeError: undefined is not a function
    at Socket.<anonymous> 

When I use the emit event in the constructor, it works (without myGame.listen() in the console.js, of course):

function Game(catalogue, speed) {


  //EventEmitter.call(this);

  this.catalogue  = catalogue || null;
  this.speed      = speed || 10;  

  var self = this;
  setInterval(function(){
    self.emit('init', (Math.random()*10).toFixed(0));
  }, 500)

}

So what is wrong here? Note that I don't need

EventEmitter.call(this); 

in the constructor in the second example. But independent from commenting this out or leaving it in, this downs change anything. Why do I need this at all? Do I?

Maybe you can help. Kind regard. Martin


Solution

  • You have to move your util.inherits(Game, EventEmitter); to before you start adding functions to your prototype. The util.inherits() meddles with the prototype, so anything placed on it before then is lost.

    Additionally, when you inherit from another object (like EventEmitter), you really should call the parent constructor (EventEmitter.call(this)) because it may need to do some initialization of its own.