0

I am very new to Javascript and I just stuck with something that works in python. The problem is that I have class where I initiate some empty lists as this.data_y_json and etc. If I make normal function inside class like normal_function(){this.data_y_json = 5} it works and the variable is changed. However, i work with d3, and there is some trick which I cant get through:

// inside class
// in constructor all this.xxx defined
// after object initiation I call set_data()
set_data(){

    d3.json("link2.json",function(data) {
        for (var i=0;i<data.d.results.length;i++){
            this.data_y_json.push(parseFloat(data.d.results[i].PE))
         ...

    //end of function
    // end of class

After calling function set_data() an error is raised: SCRIPT5007: Unable to get property 'data_y_json' of undefined or null reference

I am rewriting my visualization into OOP, before this, I had it solved with global variables and it worked fined. In python I would just passed 'self' as an argument to function, but here in javascript, passing THIS doesnt work and raises another error.

Simply said, I know the problem -> this.data_y_json is not recognized propably because of function(data) doesnt pass self of the object, but I dont know how to do it.

Thank in advance for advice

Martin
  • 2,599
  • 2
  • 8
  • 28
  • See [this post](https://stackoverflow.com/questions/22939130/when-should-i-use-arrow-functions-in-ecmascript-6). – jhpratt Aug 06 '18 at 21:31
  • 1
    quick and dirty: define `var self = this;` at the beginning of the method and then use `self` instead of `this` – fedeghe Aug 06 '18 at 22:17

1 Answers1

3

Are you in an ES2015 environment? Changing your callback to be an arrow function should scope this to be what you want

d3.json("link2.json", (data) => {
    for (var i=0;i<data.d.results.length;i++){
        this.data_y_json.push(parseFloat(data.d.results[i].PE))

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

For reading up on the arrow function and the scoping of this

AHB
  • 548
  • 2
  • 6
  • the arrow functions is equivalent to the `function ()` syntax it is just syntax sugar and just easier to write for small lambda's – rioV8 Aug 06 '18 at 22:31
  • @rioV8 Arrow functions are **not** equivalent to regular functions neither an *easier to write* version: arrow functions don't have their own `this`, they don't have the `arguments` object, they cannot be called with `new`, they have implicit `return` etc. The differences are many. – Gerardo Furtado Aug 09 '18 at 11:17
  • @GerardoFurtado: that might be the reason why sometimes `d3.select(this)` is not working and I had to use `d3.select(nodes[i])`. no implicit return if you use `{}` – rioV8 Aug 09 '18 at 13:06
  • @rioV8 Yes, but not *sometimes*: `d3.select(this)` will never work in an arrow function, as I explain [here](https://stackoverflow.com/a/45262284/5768908), [here](https://stackoverflow.com/a/43552367/5768908), [here](https://stackoverflow.com/a/50165216/5768908) and [here](https://stackoverflow.com/a/38624743/5768908). – Gerardo Furtado Aug 09 '18 at 14:14