1
componentDidMount() {
    $.ajax({
        type: 'post',
        url: 'requests.php',
        data: {requestKey: "hello"}
    }).done(function(data){
        this.setState({
            items: data
        });
    }.bind(this));
 }

 render(){
     let items = this.state.items;
     console.log(items);
     return(
         <div id="tops">
         <h1 className="header">
             What's top!
             <a href="#" className="more">more!</a>
         </h1>
         {items.map(function(item){
             return(
                 <TopsItem
                     img={item.img}
                     heading={item.heading}
                     desc={item.desc}
                 />
             );
         })}
         </div>
     );
}

The data in state.items does not effect the components in map function. And yet I get this error:

items.map is not a function

console.log(items); works after 1sec.

At first it's empty, then it gets the data in it.

2
  • items && items.map will work Commented Jul 13, 2018 at 11:31
  • @RIYAJKHAN sorry, what do you mean? Commented Jul 13, 2018 at 12:57

3 Answers 3

1

initial render needs your items array to be present in state of your component.

You should initialise items in constructor like this

this.state = {
    items = []
}
Sign up to request clarification or add additional context in comments.

3 Comments

sorry what do you mean, equation inside the object won't work!
place the above code inside constructor of your component.
Unexpected token (370:12) 368 | super(props); 369 | this.state = { > 370 | items = [] | ^ 371 | } 372 | }
0

You need a default value for your items so that it will work until your network request has finished.

You also need to make sure that you parse the JSON string in the response of your network request.

Example

class MyComponent extends React.Class {
  state = { items: [] };

  componentDidMount() {
    $.ajax({
      type: 'post',
      url: 'requests.php',
      data: {requestKey: "hello"}
    }).done(function(data){
      this.setState({
        items: JSON.parse(data)
      });
    }.bind(this));
  }

  render() {
    // ...
  }
}

4 Comments

still got the same error: items.map is not a function:(
@S.Mhm That's frustrating. Could you console.log your data in the response to your ajax request? It might not be an array in the response.
this is the data assigned to items: [{"img":"0.jpg","heading":"Proj 1","desc":"some text goes here!"},{"img":"0.jpg","heading":"Proj 1","desc":"some text goes here!"},{"img":"0.jpg","heading":"Proj 1","desc":"some text goes here!"}] :( at first items value is [] then it's the json above!
@S.Mhm Maybe it's a string. Have you tried parsing it in the response of the reqeust? JSON.parse(data)
0

Reason JavaScript's map function works with an array, and initially this.state.items are undefined until it gets response from ajax request.

the component get rendered before the response comes from ajax and it throws the error

Solution Here we can set the initial state value {items:[]}, it must be an array, so it could execute the map() any without error.

class MyComponent extends React.Class {
   constructor(props) {
       this.state = {
           items: []
       };
   }
}

1 Comment

I've done the same. but my component does not seem to be affected by the value change of items. the value of the items changes after ajax response but nothing happenes in the component. thanks

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.