Ali Ossaily
Ali Ossaily

Reputation: 35

cannot setState using axios

componentDidMount() {
  var self = this;

  axios.get('http://URL')
    .then(function (response) {
      console.log(response.data);
      this.setState({
        data: response.data
      })
    })
    .catch(function (error) {
      console.log(error);
    });
}

I got this error: TypeError: Cannot read property 'setState' of undefined

Upvotes: 1

Views: 78

Answers (4)

c-chavez
c-chavez

Reputation: 7496

You can avoid the this context problem and use this alternative. Since Axios returns a promise, you can use async/await, and don't think about the this context.

Use it like this:

async function getData(url){
    try {
        return await axios.get(url);
    } catch(error) {
        console.log(error);
    }
}

async componentDidMount(){
    let response = await getData('http://URL');
    console.log(response.data);
    this.setState({data: response.data});
 }

Looks more readable and easier to use for other functions and components as well.

Upvotes: 0

azrahel
azrahel

Reputation: 1213

You can use ES6 arrow function that automagically binds lexical parent scope for you.

componentDidMount(){
     axios.get('http://URL')
         .then( response => {
            console.log(response.data);

            this.setState({
                data: response.data
            })
     })
    .catch(error =>  {
        console.log(error);
   });
 }

Introducing self is overkill and comes from jQuery. It was used before ES6 arrow function been introduced.

You can read about auto this binding in arrow functions here:

https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4

Also check those links to better understand how this works in Javascript and the logic of scope:

https://scotch.io/tutorials/understanding-scope-in-javascript https://javascriptplayground.com/javascript-variable-scope-this/

Upvotes: 0

Vinicius Zomer
Vinicius Zomer

Reputation: 151

If you use self instead of this on setState should fix.

Upvotes: 0

Hemadri Dasari
Hemadri Dasari

Reputation: 33974

Use arrow function so that you no need to depend on local variable and scope will be taken care automatically

 componentDidMount(){
     axios.get('http://URL')
         .then( response => {
            console.log(response.data);
            this.setState({data: response.data})
     })
    .catch(error =>  {
        console.log(error);
   });
 }

Or replace this with self while doing setState like below

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

Both the above options will work. I would recommend you to go with first option

Upvotes: 1

Related Questions