2

When I Register an function as an event, the emit inside said function does not get called. The function it self is called (as tested by log). Now when I register the event using method 2, it works. Why is this?

Method 1 (Does not call event):

"use strict";
const EventEmitter = require("events");

class DiscordBot extends EventEmitter{
  constructor(key){
    super();
  }

  startBot(){
    var self = this;
    this.bot.on("ready",self.botReady);
  }

  botReady(){
    var self = this;
    self.emit("Bot_Ready");
    console.log("TESD");
  }
}

Method 2 (works):

"use strict";
const EventEmitter = require("events");

class DiscordBot extends EventEmitter{
  constructor(key){
    super();
  }

  startBot(){
    var self = this;
    this.bot.on("ready",function () {
      self.botReady();
    });
  }

  botReady(){
    var self = this;
    self.emit("Bot_Ready");
    console.log("TESD");
  }

}

Register:

    bot.on("Bot_Ready", function(){
    console.log('this happens ');
});
Alex Carter
  • 129
  • 1
  • 1
  • 7
  • 1
    Maybe you lose context and you need to use arrow function like this `this.bot.on("ready", () => this.botReady());`? – yurzui May 29 '16 at 05:16
  • 1
    In your first example, does self.botReady need to be called like self.botReady() ? – Tad Donaghe May 29 '16 at 05:16
  • https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Lexical_this – yurzui May 29 '16 at 05:19

2 Answers2

1

This creates a closure:

this.bot.on("ready",function () {
  self.botReady();
});

Method 1 doesn't:

  startBot(){
    var self = this;
    this.bot.on("ready",self.botReady);
  }

From the MDN link above:

A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.

Here is another great link that might help explain:

How do JavaScript closures work?

Note this part:

In JavaScript, if you use the function keyword inside another function, you are creating a closure.

Community
  • 1
  • 1
paulsm4
  • 114,292
  • 17
  • 138
  • 190
0

"Maybe you lose context and you need to use arrow function like this this.bot.on("ready", () => this.botReady());" - @yurzui

Works like a charm.

Alex Carter
  • 129
  • 1
  • 1
  • 7
  • 1
    No, no, no. That it (seems to) "work" isn't good enough. Please read the links in my post above and make sure you understand *WHY* one scenario works, and the other doesn't. You might also be interested in reading about [Cargo Cult Programming](https://en.wikipedia.org/wiki/Cargo_cult_programming). Finally, be sure to read about [Arrow Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) and [this Closures](https://www.sitepoint.com/es6-arrow-functions-new-fat-concise-syntax-javascript/). – paulsm4 May 29 '16 at 05:35
  • PS: Please edit your response: 1) explain why "Method 1" works and "Method 2" doesn't, and 2) how the (new, ES6) "arrow function" accomplishes the same thing as "Method 2". I'd be happy to change the downvote to an upvote :) Please, too, feel free to *ACCEPT* your response after you've elaborated on the "why" behind the "what". – paulsm4 May 29 '16 at 21:05