1

first time ReactJS user and am having issues looping through data I retrieved via AJAX to populate. I get a number of errors ranging from Uncaught TypeError: Cannot read property 'map' of undefined. Am I supposed to be setting the props or a state?

var Posts = React.createClass({
getInitialState: function() {
     return ({
        posts: []
     })
},

loadPosts: function(){
    var posts = null;
    axios.get('/getposts')
      .then(function (result) { 
        posts = result.data;    
      })
      .catch(function (error) {
        console.log(error);
      });
},

postReadMode: function() {
    return (
        <div>
        </div>
    )
},

render: function() {
    return (
        <div>
            Hello, {this.props.posts.map(function(item, i){
                return item.title;
            })}
        </div>
    )
}

})

The data returned is somewhat of a multidimensional object/array:

Obj:
  0: 
     title: 'Title 1',
     date: '12-2-2015',
     content: 'asdf'
  1: 
     title: 'Title 2',
     date: '1-25-2016',
     content: 'asdfasdf'
9
  • You always SET state, you pass state as props. Commented Feb 10, 2017 at 0:50
  • In reactJS you set state using the setState method. Try doing that, and it may solve your problem. Commented Feb 10, 2017 at 0:52
  • In addition, where you're using props, you should be using state in your render function. Commented Feb 10, 2017 at 0:55
  • So I did a this.setState({posts : result.data}); inside the AJAX call, and then {this.state.posts.map(function(item, i){ return item.title})} with it returning a blank but I know the result.data have values in it Commented Feb 10, 2017 at 1:03
  • if you just leave this.state.posts without the map, do you see anything? Commented Feb 10, 2017 at 1:17

1 Answer 1

1

There are 2 points we need to be cleared:

  • Using {this.props.posts.map(..) is incorrect. posts (in this case) is state because its value is changed (from [] to AJAX response after the AJAX request). You must use {this.state.posts.map(...) in render method.

  • You should implement the AJAX call inside componentDidMount method:

If you need to load data from a remote endpoint, this is a good place to instantiate the network request.

componentDidMount: function() {
    var self = this;
    axios.get('/getposts')
        .then(function (result) { 
            self.setState({
                posts: result.data
            });
        })
        .catch(function (error) {
            console.log(error);
        });
}

Set setState method will change the posts state value and therefore render method will run again to display new UI.

If you want a much better way to handle async networking stuff, give a try on Redux AsyncActions.

Sign up to request clarification or add additional context in comments.

1 Comment

Good catch, don't know how I missed that. Guess I was focused on everything else.

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.