Sriraman
Sriraman

Reputation: 7937

Couldn't setState from the then function of the Promise

I'm trying to update the state from the promise which I received using the fetch function.

componentDidMount(){

fetch(url).then((responseText) => {

     var response = responseText.json();

     response.then(function(response){
         this.setState(response);
     });

  });
}

I was getting the error that the setState is not an function

Then, I tried to bind(this) to pass the this value like below.

componentDidMount(){

fetch(url).then((responseText) => {

     var response = responseText.json();

     response.then(function(response){
         this.setState(response);
     });

  }).bind(this);
}

It is not working now also. Same error again.

Upvotes: 22

Views: 22824

Answers (4)

Charles Jennings
Charles Jennings

Reputation: 11

You also have the wrong method to setState it should look something like setState({name : 'string'})

Upvotes: 0

Sriraman
Sriraman

Reputation: 7937

Sorry, Just now found that I didn't bind the this variable properly.

Now, It is fixed.

componentDidMount(){

  fetch(url).then((responseText) => {

    const response = responseText.json();

    response.then(function(response){
        this.setState(response);
    });

  }.bind(this));

}

Upvotes: 14

Nicklas Nygren
Nicklas Nygren

Reputation: 2605

This is because of the scoping of this, so you're on to something when you're trying to use Function.prototype.bind. Your mistake is that you don't bind all the way down to the last anonymous function. What you probably want to do is use arrow functions all the way, like this:

componentDidMount(){
    fetch(url)
        .then((responseText) => responseText.json())
        .then((response) => this.setState(response));
}

Arrow functions always keep the context of this.

Upvotes: 36

nils
nils

Reputation: 27174

Your second promise doesn't have the current this context. You can use an arrow function here as well.

componentDidMount(){
  fetch(url).then((responseText) => {
     return responseText.json();
  })
  .then((response) => {
     this.setState(response);
  });
}

Also, chaining instead of nesting your promises will help with the legibility and might help you to avoid callback hell.

Upvotes: 3

Related Questions