sinawic
sinawic

Reputation: 157

get data using $.ajax in React does not work

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.

Upvotes: 1

Views: 199

Answers (3)

Tholle
Tholle

Reputation: 112787

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() {
    // ...
  }
}

Upvotes: 0

ATUL DIVEDI
ATUL DIVEDI

Reputation: 156

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: []
       };
   }
}

Upvotes: 0

Dinesh undefined
Dinesh undefined

Reputation: 5546

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 = []
}

Upvotes: 1

Related Questions