Fidel
Fidel

Reputation: 922

emit() and on() not working

i'm learning nodejs and some issues appeared, that emit() and on() is not a function..

here's my emitter.js fie

   function Emitter(){
    this.events = {};
}

Emitter.prototype.on = function(type, listener){
    this.events[type]=this.events[type]||[];
    this.events[type].push(listener);
}

Emitter.prototype.emit = function(type){
    if (this.events[type]) {
        this.events[type].forEach(function(listener){
            listener();
        });
    }
}

and here's my app.js file

//Emitter
var Emitter = require('./emitter');
Emitter.on('greet', function(){
    console.log('a greeting occured!`');
});
console.log('hello');
Emitter.emit('greet');

and here's the error TypeError: Emitter.on is not a function

when i instantiated the Emitter: var emitter = new Emitter();

and this the error: TypeError: Emitter is not a constructor then, i export the modules using this literal syntax: module.exports= {emit: Emit} the error still appeared that the new Emitter() is not a constructor

so, i export it with this: module.exports = Emitter; instead with this pattern module.exports = {emit: Emitter} and i still don't know why i can't export it with literal, any idea?

Upvotes: 0

Views: 2960

Answers (2)

Iain J. Reid
Iain J. Reid

Reputation: 988

There are two issues that should be addressed, firstly you need to export the Emitter function from the file that it was defined in to be able to require it in another file, you can do this simply like this:

module.exports = function Emitter() {
  this.events = {}
}

// ... etc

You also need to use the new operator on your Emitter function to instantiate a new copy of the object to allow you to then use the functions on and emit that you defined. This is because the methods are part of the objects prototype. You can do this like this:

const emitter = new Emitter()

emitter.on("greet", function () {
  // ... etc
})

It might be worth noting that Node.js already has an inbuilt Events module that covers what you are trying to achieve, and you can find documentation in their API docs.

Upvotes: 0

PeterMader
PeterMader

Reputation: 7285

You've created a class. Create an instance of it using new Emitter(). Also, you have to export and import the Emitter class:

// emitter.js
function Emitter(){
  this.events = {};
}

Emitter.prototype.on = function(type, listener){
  this.events[type]=this.events[type]||[];
  this.events[type].push(listener);
}

Emitter.prototype.emit = function(type){
  if (this.events[type]) {
    this.events[type].forEach(function(listener){
      listener();
    });
  }
}
// Export the Emitter class: module.exports = Emitter;

// app.js
// Import the emitter class: var Emitter = require('./emitter');
var emitter = new Emitter();
emitter.on('greet', function(){
  console.log('a greeting occured!`');
});
console.log('hello');
emitter.emit('greet');

Whenever you use the new operator with a constructor function, a new object is created. The prototype of that object will the prototype property of the constructor function. Then, the constructor is called with the new object (this in the constructor is the new object).

Upvotes: 3

Related Questions