0

I don't understand JavaScript scope when it comes to object variables. I have the following class defined:

class DataHandler {
  constructor(boardIDA, boardIDB, accessToken, eventA, eventB) {
    this.times = [];
    this.eventA = eventA;
    this.eventB = eventB;
    this.apiURLA = "https://api.particle.io/v1/devices/" + boardIDA + "/events/" + eventA + "/?access_token=" +
      accessToken;
    this.apiURLB = "https://api.particle.io/v1/devices/" + boardIDB + "/events/" + eventB + "/?access_token=" + accessToken;
    this.eventListenerA = new EventSource(this.apiURLA);
    this.eventListenerB = new EventSource(this.apiURLB);
    this.addListener(this.eventListenerA,
      eventA);
    this.addListener(this.eventListenerB, eventB);
  }
  addListener(eventSrc, eventName) {
    eventSrc.addEventListener(eventName, function(info) {
      alert(eventName);
      var parsedData = JSON.parse(info.data);
      this.times.push(parsedData);
    });
  }
}

The issue is with this.times. I have declared it in the constructor. However, I can't seem to access it in addListener — I get an error saying that I'm trying to call push on undefined. What am I doing wrong?

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
tjb272
  • 23
  • 1
  • 4

1 Answers1

2

You are not accessing it in addListener, you are trying to access it in the anonymous event handler, which is called with a different this.

addListener(eventSrc, eventName) {
  var handler = function(info) {
    alert(eventName);
    var parsedData = JSON.parse(info.data);
    this.times.push(parsedData);
  };
  eventSrc.addEventListener(eventName, handler.bind(this));
}
Igor
  • 15,833
  • 1
  • 27
  • 32
  • would changing the anonymous function (which you've now changed to handler, but thinking of original code) to an arrow function also work? therefore negating the need for bind - considering the code already uses ES2015 `class`, then why not use `=>` as well (if it's an alternative) – Jaromanda X Jan 09 '17 at 22:25
  • @JaromandaX - yes - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_binding_of_this – Igor Jan 09 '17 at 22:34
  • "*…called in a different scope*" might be better as "called with a different *this*" since the scope from which a function is called does not affect how its *this* is set. ;-) – RobG Jan 09 '17 at 22:47
  • @RobG - you are right, thank you – Igor Jan 10 '17 at 03:00