vimuth
vimuth

Reputation: 5612

TypeError: this.state is null for $.ajax request

var Movie = React.createClass({
  getInitialState: function() {
    $.ajax({
      url: "getjsonarray.php",
      dataType: 'json',
      method: "POST",
      data: {
        startpoint: 0,
        perpage: 2
      },
      success: function(data) {
        this.setState({
          json: data
        }, function() {
        }.bind(this));
      }.bind(this),
    });
    return null;
  },
  render: function() {
    return (
      <div>
        {
          this.state.json.map(function(object, i){
            return (
              <div key={i}>                          
                <h1>Movie {i}</h1>
                <h2>Genre {i}</h2>
              </div>  
            );
          })
        }
      </div>
    );
  }
});
ReactDOM.render(<Movie/>, document.getElementById('container'));

Here I'm trying to get json array from back end iterate through array via react js. But I only get this error,

TypeError: this.state is null

is there any way to return value with ajax responcejson array?

This is what I get from back end,

[{"id":"1","image":"http:\/\/images.prd.mris.com\/image\/V2\/1\/Yu59d899Ocpyr_RnF0-8qNJX1oYibjwp9TiLy-bZvU9vRJ2iC1zSQgFwW-fTCs6tVkKrj99s7FFm5Ygwl88xIA.jpg","price":"$1,975,000 ","address":"609 W Gravers Ln","area":"4,820 SqFt","beds":"5","baths":"5","desc":"Situated between fairmount park and the prestigious philadelphia cricket club, this beautiful 2+ acre property is truly","subdesc":"Courtesy of HS Fox & Roach-Chestnut Hill Evergreen"},{"id":"2","image":"http:\/\/images.prd.mris.com\/image\/V2\/1\/vGoNjc2jHGb87GlnnDQlf6LxeOUgIOn0bL6Wvn1nEnig2Ntq6W7xN5cOQBZZeNxl9O42DOkHUw0LNnj1ZB2KHA.jpg","price":"$1,500,000","address":"1220-32 N Howard St","area":"4,900 SqFt","beds":"1","baths":"1","desc":"A once in a lifetime opportunity to own a unique live \/ work space in one of philadelphia's most popular neighborhoods.","subdesc":"Courtesy of ll Banker Preferred-Philadelphia"}]

Upvotes: 0

Views: 354

Answers (3)

Mohit Verma
Mohit Verma

Reputation: 1660

You should get server data/response in componentDidMount lifecycle method of your component. Your code can be like this

    var Movie = React.createClass({

    getInitialState: function () {
      this.state = { json: [] };
    },

    componentDidMount: function () {
      var self = this;

      $.ajax({
        url: "getjsonarray.php",
        dataType: 'json',
        method: "POST",
        data: {
          startpoint: 0,
          perpage: 2
        },
        success: function (response) {

          /* okay, now re-render component with received response */
          self.setState({
            json: response
          });

        }
      });

    },

    render: function () {
      /* in initial render json array is empty */
      var json = this.state.json;

      return (
        <div>
          {
            json.map(function (object, i) {
              return (
                <div key={i}>
                  <h1>Movie {i}</h1>
                  <h2>Genre {i}</h2>
                </div>
              );
            })
          }
        </div>
      );
    }
  });

  ReactDOM.render(<Movie/>, document.getElementById('container'));

Upvotes: 0

Pablo Lozano
Pablo Lozano

Reputation: 10342

Your problem is that your code breaks the life cycle of that component. You should 1. make the AJAX call and, once you have the value you need, then create the component. 2. create the component and then update it using the values from the AJAX response.

Upvotes: 0

finalfreq
finalfreq

Reputation: 6980

The problem here is that ajax is async so getInitialState goes first, then it goes straight to render, the api call is still in transit and you don't actually set state until the response is received. I would suggest setting initial state of json to an empty array and then add a componentDidMount function that does the ajax request and updates the state of json.

getInitialState: function() {  
    return {
      json: []
    }
},             

componentDidMount: function() {
   $.ajax({
        url: "getjsonarray.php",
        dataType: 'json',
        method: "POST",
        data : {startpoint: 0, perpage: 2},
        success: function(data) {  
          this.setState({json: data}, function(){

          }.bind(this));

        }.bind(this),
    });
},

In my own apps whenever i have a component that is dependent on a api call to get its data, I add a loading state to my component that comes in initially as true, and then while true I render something different or some sort of spinner. Then once the api call is finished it will set the loading state to false and update the data state.

Upvotes: 1

Related Questions