2

I'm struggling with this for almost 2hours and still not getting it.=( For explanation I got the following code.

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

function a (){
    //this is my first function
    var b_obj = new b();
    b_obj.on('event',function(){
        console.log('Something happened!');
    });
};

function b (){
    //this is my second function
    events.call(this);
    this.emit('event');
};

util.inherits(b, events);
a();

So what I try to do is: I got a function called "a". This function calls a second function called "b". This function validates some data and emits events depending on the result of the validation.

What I found out is, that the listener works fine and the event is correct emitted. But, as it looks like the event is emitted in the context of function b and the listener works in the context of function a. For further investigations I added the following line to function b:

this.on('event', function(){
        console.log('event emitted!');
    });

And this works. Can anybody help me? I'm sure the solution is pretty simple. =(

zeekrey
  • 391
  • 6
  • 16
  • Yes, the event is triggered *on* the `obj_b` instance, and that's the context for all listeners. – Bergi Dec 20 '14 at 18:44
  • possible duplicate of [How to access the correct \`this\` / context inside a callback?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Bergi Dec 20 '14 at 18:45
  • @Bergi: The problem isn’t the value of `this`, but the relative timing of the `emit` and `on` calls, so it is not a duplicate. – icktoofay Dec 22 '14 at 00:11
  • @icktoofay: I must have misunderstood the term "context", yes. I already wondered how "*the listener works fine and the event is correct*" though `emit` is synchronous. – Bergi Dec 22 '14 at 11:57

2 Answers2

2

If what you mean is inform the function a() when the validation process in function b() is complete, then just emit the event from b after doing the validation.
I use setTimeout() for asyncronous example.

var EventEmitter = require("events").EventEmitter;
var theEvent = new EventEmitter();

function a(){
  console.log('preparing validation..');
  theEvent.on('validationDone', function(validationResult){
    console.log('validation result is ' + validationResult);  // prints 'validation result is true' in the next 2 sec
  });
  b();
}

function b(){
  setTimeout(function(){
    var result = true;
    theEvent.emit('validationDone', result);
  }, 2000);
}

a();
bagz_man
  • 555
  • 2
  • 8
  • 20
  • In Node.js, you’d probably use `process.nextTick`. – icktoofay Dec 22 '14 at 00:10
  • of course in practical use-case we should use process.nextTick instead of setTImeout 0ms. I just using it as the example that theEvent will emit event in the next 2 sec. – bagz_man Dec 22 '14 at 01:00
-1

The event handler function is always called in the context of the object that emits the event, in this case b. In your example you could simply do

function a() {
  var self = this;

  ...
}

to remember a's context, but I assume your real code is different and you may not have your event handler specified as a closure, so you can instead bind your handler to the desired object before setting it:

function a (){
    //this is my first function
    var b_obj = new b();
    b_obj.on('event', handlerFunction.bind(this));
}

In this case, your handlerFunction will always be called in the context of a. The bind method returns a new function that is bound to the object you provided, see Mozilla's documentation.

PS. You may want to phrase your questions clearer and provide better examples before you post in the future.

Antony Mativos
  • 863
  • 1
  • 8
  • 5
  • Hi Antony, thanks for your reply. But I don't get it. Adding 'var self = this;' didn't change anything. In addition I tried it with '.bind(this)'. It's still not working. If you tell me what is unclear I'll try to explain in more detail. – zeekrey Dec 20 '14 at 15:55
  • The problem is the timing, not the value of `this`. – icktoofay Dec 22 '14 at 00:10
  • The real problem is poorly asked question, I too noticed that event is emitted before the listener is setup, but assumed that the question is really about context / `this` value. – Antony Mativos Dec 22 '14 at 15:14