pedalpete
pedalpete

Reputation: 21536

Node.js EventEmitter function error `listener must be a function` when `typeof` returns function - could be scope issue

I have an object which is being interacted with from a few different node.js modules.

I want to have some of these modules be able to add eventListeners to the object.

I have an events file where the event emitters are attached and removed. It looks basically like this

    function onData() {
        if(!this._eventEmitter) this._eventEmitter = new EventEmitter();
        this._eventEmitter.on('data', this._callback);
    }


    function removeOn() {
        console.log(typeof this._callback, this._callback.name);
        try {
         this._eventEmitter.removeListener('data', this._callback.name);
        } catch(e) {
            console.log('err', e);
        }
    }

module.exports = {
     on: onData, 
     off; removeOn
}

I'm adding event listeners pretty simply through just

var evt = require('./libs/events');

// a bunch of stuff
function fctName(){ 
   console.log('this is the callback');
};
this._callback = fctName;

evt.on.call(this);

var self = this;
setTimeout(function(){
  evt.off.call(self);
},3000);

The on method fires perfectly on queue. When I try to remove the listener with the off method, the console shows function fctName showing that this._callback is in fact a function and the name is known. But the try fails and the error returned is [TypeError: listener must be a function].

I thought the issue might have been the scope of the function not being available, but the function should be attached to the this object which is being passed around. I'm kind of at my wits end with this.

---------------- Update ----------------------------

I've removed the .name from this._callback in removeListener as @bergi recommended. I no longer get the error, but the listener is still not removed.

I've also tried

this._eventEmitter.removeAllListeners('data');
this._eventEmitter.removeAllListeners();

neither of which removed the listener.

The console output of this._eventEmitter is

 { domain: null,
  _events: { data: [Function: fctName] },
  _maxListeners: 10 }

I can clearly see the data and fctName of the function I'm trying to remove, but cannot remove it in any way.

Upvotes: 0

Views: 1056

Answers (1)

Bergi
Bergi

Reputation: 664196

removeListener expects the callback itself, not it's name. Only the first parameter, the event name, is supposed to be a string, the second one should be the function.

function removeOn() {
    this._eventEmitter.removeListener('data', this._callback);
}

Upvotes: 2

Related Questions