Node.js EventEmitter and multiple levels of inheritance

eventemitter, javascript, node.js, prototypal-inheritance

Solution

In your example, there is no kind of inheritance relationship between homeController and baseController. Also, this line:

homeController.prototype = baseController;

Is redundant, since the prototype property only matters for constructor functions.

If you want to set up baseController so whoever extends/ inherits from it will have the 'request' listener assigned to it, first you should define it like this:

var BaseController = function(){
    this.on('request', function(){
       console.log('...');
    });
};

BaseController.prototype = new events.EventEmitter();
BaseController.prototype.constructor = BaseController;

It will be even better if you can make the handler assignment in an initiliazation method (doing work in a constructor function is usually bad design):

var BaseController = function(){};

BaseController.prototype = new events.EventEmitter();
BaseController.prototype.init = function(){
    this.on('request', function(){
       console.log('...');
    });
};

And then, all you need to extend it in your HomeController is to do this:

var HomeController = function(){};
HomeController.prototype = new BaseController();

var homeController = new HomeController();
homeController.init(); // If you went with the initialization approach I offered...

Please note, that unless you must do it, creating long inheritance chains in JS isn't very nice or maintainable. If you can, I encourage you to avoid doing it and try finding a more maintainable solution.

Problem

I'm trying to figure out the best approach to multiple levels of inheritance when using the Node.js `EventEmitter` class. The setup is I am developing an MVC framework for Node.js using Controllers that can have base Controllers, but Controllers can emit events that also emit the same event on its base Controller. So far I have: ``` var events = require('events'); var util = require('util'); var Controller = function() { }; util.inherits(Controller, events.EventEmitter); var baseController = new Controller(); baseController.on('request', function() { console.log('Calling request event on baseController'); }); var homeController = new Controller(); homeController.prototype = baseController; homeController.on('request', function() { console.log('Calling request event on homeController'); }); homeController.emit('request'); ``` ...but only "Calling request event on homeController" is output, I want both 'request' events to fire. How do I do this? Maybe I need to completely change my approach? Update: thanks for everyone's help. As Naor Biton suggested, there was no inheritance between baseController and homeController because the 'prototype' property only matters for constructor functions. I'm always getting my constructor functions and object instances mixed up. I eventually settled for the following: ``` var events = require('events'); var util = require('util'); var Controller = function() { }; util.inherits(Controller, events.EventEmitter); Controller.createBaseController = function() { var BaseController = function() { }; util.inherits(BaseController, Controller); return new BaseController(); }; Controller.inheritController = function(baseController) { var NewController = function() { }; NewController.prototype = baseController; return new NewController(); }; var baseController = Controller.createBaseController(); baseController.on('request', function() { console.log('Calling request event on baseController'); }); var homeController = Controller.inheritController(baseController); homeController.on('request', function() { console.log('Calling request event on homeController'); }); homeController.emit('request'); ```

Original source

Related problems