Jay Jeong
Jay Jeong

Reputation: 994

Weird behaviour related to scope in javascript and d3.js

I am writing code in react.js combining with d3.js. But there is a small, but something I don't understand its behaviour..

 componentWillMount() {
     this.setState({
         dummyData: [{
               price: 13,
               age: 43,
               etc: 99
               },
               {
                price: 33,
                age: 22, 
                etc: 100
               }]
     }


 componentDidMount () {
     this.keys = Object.keys(this.state.dummyData[0]);
     console.log(this.keys) // ["price", "age", "etc"]
   }

  someMethod(){
      console.log(this.keys) // ["price", "age", "etc"]

      this.svg.append('g')
    .selectAll('g')
        .data(this.state.dummyData)
        .enter()
    .append('g')
        .attr('transform', d => { 
            console.log(this.keys); // ["price", "age", "etc"]
            return 'translate(' + this.x0(d.name) + ', 0)';
        })
    .selectAll('rect')
        .data( function(d){ 
            console.log(this.keys); // undefined
            return this.keys.map( function(key){ return { key: key, value: d[key] }; }); }) // This statement causes an error
        .enter()
    .append('rect')
        .attr('x', function(d){ return this.x1(d.key) })
        .attr('y', function(d){ return this.y(d.value) })
        .attr('width', this.x1.bandwidth())
        .attr('height', function(d){ return height - this.y(d.value) })
        .attr('fill', function(d){ return this.z(d.key) });

   }

   ...

As you can see from the code, this.keys remains its value until it reaches second data call. I really don't get what happens at that point.

Upvotes: 0

Views: 23

Answers (1)

A. Llorente
A. Llorente

Reputation: 1162

That's because of how scope and functions work in javascript. If you change your function to an arrow function it will automatically bind the scope and you will see what you expect.

As a quick explanation: Arrow functions autobind the scope where they are declared while functions don't so you have to explicitly bind the scope you want to the function.

Upvotes: 1

Related Questions