2

I can't get a constructor variable within my fetch call using javascript and react. I would like the value of this.state.numXLabels within the .then(function(json) callback, but I get TypeError: Cannot read property 'state' of undefined(…). What is the proper way of doing this? Here is the relevant code:

TypeError: Cannot read property 'state' of undefined(…)

import React, { Component } from 'react'
class StockGraph extends Component {

constructor(props) {
    super(props);
    this.state = { numXLabels: 0 }
     var url = 'https://www.quandl.com/api/v3/datasets/WIKI/MSFT'+
           '.json?api_key=bCRpjzvgPNkxLzqAv2yY';
    fetch(url)
    .then(function(response) {
      return response.json()
    })
    .then(function(json) {
      console.log(this.state.numXLabels);
       //this.setState({
        // numXLabels: 30
       //})
    })
  }
...
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
joshlevy89
  • 269
  • 1
  • 6
  • 13
  • Have a look at [Is it bad practice to have a constructor function return a Promise?](http://stackoverflow.com/q/24398699/1048572) for the general problem, although there's probably a react-specific solution. – Bergi Apr 24 '16 at 11:36

1 Answers1

3

Do not try to use state or make ajax calls in the constructor of your React component. Instead, put that call inside one of the lifecycle methods that fires immediately, like componentWillMount. Also to access this.state inside of your ajax callback, you will need to bind this to the function. Using the fat arrow function syntax is the most straightforward way.

class StockGraph extends Component {
    constructor(props) {
        super(props);
        this.state = { numXLabels: 0 }
    }

    componentWillMount() {
        var url = 'https://www.quandl.com/api/v3/datasets/WIKI/MSFT'+
           '.json?api_key=bCRpjzvgPNkxLzqAv2yY';
        fetch(url)
        .then((response) => {
           return response.json()
         })
        .then((json) => {
            console.log(this.state.numXLabels);
            //this.setState({
             // numXLabels: 30
           //})
        })
    }
    ...
Andy Noelker
  • 10,949
  • 6
  • 35
  • 47
  • thanks! the binding was the key. moving to componentWillMount is also nice for structural cleanliness. fat arrow syntax is a great tip. can also be achieved like : .then(function(json){ console.log(this.state.numXLabels); }.bind(this)) – joshlevy89 Apr 23 '16 at 17:05