1

I'm trying to make a simple AJAX call using Axios in React, but I can't figure out where I'm going wrong.

Here is what I have so far (within my component):

ComponentDidMount() {
   axios.get('https://jsonplaceholder.typicode.com/users')
      .then( res => {
         const users = res
         this.setState({ users });
      });
}

render() {
   console.log(this.state.users)   // returns the **initialised EMPTY array**
   return (
   <div>
      {this.state.users.map( user => <p>{user.name}</p>)} // returns nothing
   </div>
   )
}

I am accessing a simple array at the URL given in the .get() method (check it out to see it's structure if necessary). I then chain on the .then() promise and pass the res argument in an arrow function.

Then I assign the users variable to the result, and attempt to set the state as this. So at this point I'm expecting this.state.users to equal the resulting array.

However...

A) When I try console.log(this.state.users), it returns the initialised empty array

B) When I try to render a map of the array, iterating through the name property on each object, again, nothing.

Where am I going wrong?

2 Answers 2

2

A part from the typo (as Phi Nguyen noted), a few other things to fix:

1) Axios resolves the promise with a response object. So to get the results you need to do:

   axios.get('https://jsonplaceholder.typicode.com/users')
     .then( res => {
      const users = res.data;  // Assuming the response body contains the array
      this.setState({ users });
    });

Check out the docs about the response object here: https://github.com/mzabriskie/axios#response-schema

2) If there's an exception (your request fails) you probably want to handle it instead of swallowing it. So:

 axios.get('https://jsonplaceholder.typicode.com/users')
   .then( res => {
     const users = res.data;  // Assuming the response body contains the array
     this.setState({ users });
   })
   .catch(err => {
      // Handle the error here. E.g. use this.setState() to display an error msg.
   })
Sign up to request clarification or add additional context in comments.

2 Comments

That worked - thanks. I'm a bit confused though - when I console.log the results, two values are returned: [], and the expected array from the API. This presumably can be explained by the state value being returned once on initialisation, and then again with componentDidMount. However, when I try and access a single object in the array, this.state.users[0] for example, it tries to access the empty array. I can only get to it by mapping through the array. Is there a way to target the updated this.state.users value every time, and avoid pulling in the initial state value?
Every time you call this.setState, the render method is called again to reflect the new state of the component. See this chart here: imgh.us/react-lifecycle.svg So you have an initial render (when users is not initialised), then you have a second one after componentDidMount and a third one after you call setState (at this point you have the list of users). You can initialise the list in you component constructor. Normally in the render method you can to check if this.state.users is empty and display a loader or something.
2

typo. It should be componentDidMount instead of ComponentDidMount.

Comments

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.