5

Just started using ReactJS and JS, is there a way to return the JSON obtained from APIHelper.js to setState dairyList in App.jsx?

I think I'm not understanding something fundamental about React or JS or both. The dairyList state is never defined in Facebook React Dev Tools.

// App.jsx
export default React.createClass({
  getInitialState: function() {
    return {
      diaryList: []
    };
  },
  componentDidMount() {
    this.setState({
      dairyList: APIHelper.fetchFood('Dairy'), // want this to have the JSON
    })
  },
  render: function() {
   ... 
  }


// APIHelper.js
var helpers = {
  fetchFood: function(category) {
    var url = 'http://api.awesomefoodstore.com/category/' + category

    fetch(url)
    .then(function(response) {
      return response.json()
    })
    .then(function(json) {
      console.log(category, json)
      return json
    })
    .catch(function(error) {
      console.log('error', error)
    })
  }
}

module.exports = helpers;
2
  • Is your APIHelper.js file even syntactically correct? After you fix it, another thing: APIHelper.fetchFood is asynchronous. Commented Aug 3, 2016 at 23:21
  • @zerkms Thanks, just noticed the closing brace for fetchFood was after var url. Is there a better way to fetch the data, wait for the response and then go from there? Commented Aug 3, 2016 at 23:28

2 Answers 2

8

Since fetch is async you'll need to do something like this:

componentDidMount() {
  APIHelper.fetchFood('Dairy').then((data) => {
    this.setState({dairyList: data});
  });
},
Sign up to request clarification or add additional context in comments.

2 Comments

Sweet! Thanks for your answer it helped.
@Nikkawat Great! If there's nothing else you should click the checkmark next to this answer.
1

It works! Made changes according to Jack's answer, added .bind(this) in componentDidMount() and changed fetch(url) to return fetch (url)

Thanks! I now see State > dairyList: Array[1041] with all the elements I need

// App.jsx
export default React.createClass({
  getInitialState: function() {
    return {
      diaryList: []
    };
  },
  componentDidMount() {
    APIHelper.fetchFood('Dairy').then((data) => {
      this.setState({dairyList: data});
    }.bind(this));
  },
  render: function() {
   ... 
  }


// APIHelper.js
var helpers = {
  fetchFood: function(category) {
    var url = 'http://api.awesomefoodstore.com/category/' + category

    return fetch(url)
    .then(function(response) {
      return response.json()
    })
    .then(function(json) {
      console.log(category, json)
      return json
    })
    .catch(function(error) {
      console.log('error', error)
    })
  }
}

module.exports = helpers;

3 Comments

FWIW, You shouldn't need .bind(this) this automatically happens with the "fat arrow" (() => {} style.
Without .bind(this) I get an error Uncaught (in promise) TypeError: Cannot read property 'setState' of undefined
That's interesting. The docs, and my experience say otherwise, but whatever works!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.