8

I'd like to have something like this work:

var Events=require('events'),
    test=new Events.EventEmitter,
    scope={
        prop:true
    };

test.on('event',function() {
   console.log(this.prop===true);//would log true
});
test.emit.call(scope,'event');

But, unfortunately, the listener doesn't even get called. Is there any way to do this w/ EventEmitter? I could Function.bind to the listener, but, I'm really hoping EventEmitter has some special (or obvious ;) way to do this...

Thanks for the help!

Lite Byte
  • 689
  • 1
  • 6
  • 11

3 Answers3

11

No, because the this value in the listener is the event emitter object.

However what you can do is this

var scope = {
  ...
};
scope._events = test._events;
test.emit.call(scope, ...);

The reason your event handler did not get called is because all the handlers are stored in ._events so if you copy ._events over it should work.

Raynos
  • 166,823
  • 56
  • 351
  • 396
2

That won't work, and emit only has a convenient way to pass parameters, but none for setting this. It seems like you'll have to do the binding stuff yourself. However, you could just pass it as a parameter:

test.on('event',function(self) {
   console.log(self.prop===true);//would log true
});
test.emit('event', scope);
thejh
  • 44,854
  • 16
  • 96
  • 107
  • Like this for simplicity! However, if the emit is not under your control but the framework's that won't fix the problem, unfortunately. – Thomas Fankhauser Jul 01 '13 at 10:16
  • All evidence to the contrary. 4 years later, the accepted answer still proves to be valid in every version of Node JS: 0.10.38, 0.12.4, IO.JS 2.2.1. Works like a charm :) – vitaly-t Jun 07 '15 at 01:57
0

I came across this post when Google searching for a package in NPM which handles this:

var ScopedEventEmitter = require("scoped-event-emitter"),
    myScope = {},
    emitter = new ScopedEventEmitter(myScope);

emitter.on("foo", function() {
    assert(this === myScope);
});

emitter.emit("foo");

Full disclosure, this is a package I wrote. I needed it so I could could have an object with an EventEmitter property which emits for the containing object. NPM package page: https://www.npmjs.org/package/scoped-event-emitter

Rich Remer
  • 2,123
  • 1
  • 21
  • 22
  • The accepted answer works perfectly, there is no need for a whole extra library :) – vitaly-t Jun 07 '15 at 01:59
  • It's called code re-use. The "whole extra library" is a 37 line Javascript file, but because it's a published package, you can use it in many projects without looking for that one project you added the accepted answer to. In addition, the accepted answer did not exist when this was posted. – Rich Remer Nov 29 '17 at 05:49