2

I'm gettin Json object like this from a service

{"0":{"UserID":1,"Gender":"F","Age":1,"Occupation":10,"Zip-code":48067},
"1":{"UserID":2,"Gender":"M","Age":56,"Occupation":16,"Zip-code":70072},
"2":{"UserID":3,"Gender":"M","Age":25,"Occupation":15,"Zip-code":55117},
"3":{"UserID":4,"Gender":"M","Age":45,"Occupation":7,"Zip-code":2460},"4":}

Then using React am trying to map it to a state, but it's an object not an array of objects

class App extends Component {
  constructor() {
    super();
    this.state = {
      users: []
    }
  }
  componentDidMount() {
    this.getUsers();
  };

  getUsers() {

    axios.get(`${SERVICE_URL}/users`)
    .then((res) => { 
      console.log(res.data); // I can see the data in the console
      this.setState({ users: res.data.map((data) => {return (data.key, data.value)} }); })
    .catch((err) => { console.log(err); });
  }

I though something like this might work, but no.

this.setState({ users: res.data.ToArray().map((data) => {return (data.key, data.value)})})})

Final update, this is what worked. (probably still cleaner way but this works)

    class App extends Component {
    constructor() {
      super();
      this.state = {
        users: []
      }
    }
    componentDidMount() {
      this.getUsers();      
    };

    getUsers() {      
      axios.get(`${SERVICE_URL}/users`)
      .then((res) => {  

        this.setState({ users: Object.values(JSON.parse(res.data))});

       })   
      .catch((err) => { console.log(err); });
    }

  render() {

    return (
     <div>
     <table class='userList'> 
        <tr> 
            <td>UserId</td>
            <td>Gender</td>
            <td>Age</td>
            <td>Occupation</td>
        </tr>        

            {this.state.users.map(({UserID, Gender, Age, Occupation}) => {
              return (
                <tr key={'user'+UserID}>
                    <td> { UserID } </td>
                    <td> { Gender } </td>
                    <td> { Age } </td>
                    <td> { Occupation } </td>              
              </tr>
            )})}
        </table>
      </div>
    );
  }
}

export default App;
3
  • What do you expect users to be? Commented Jun 14, 2018 at 15:46
  • @TypeError: res.data.map is not a function ... so I cant use that. I'd be happy to get any data passed into the state and I can work from there Commented Jun 14, 2018 at 15:51
  • You want an array of users right [{..user_object..}, {..user_object..}]? Commented Jun 14, 2018 at 16:12

3 Answers 3

2

Try to parse it before with JSON.parse(res), and then you can map your array like you're doing to set your state

Sign up to request clarification or add additional context in comments.

2 Comments

error : JSON.parse: unexpected character at line 1 column 2 of the JSON data"
This helped, thank you. If you can see any good refactorings in my updated question code ill accept your.
1

As far as I understood your problem is that you have an object as input and you need to convert it into an array and set it in a variable. You can use Object.values

this.setState({ users: Object.values(res.data)});

EDIT

You can improve your code as following

this.setState({ users: Object.values(res.data)});
{this.state.users.map(([UserID, Gender, Age, Occupation, ...rest]) => {
     return (
         <tr>
             <td> { UserID] } </td>
             <td> { Gender } </td>
             <td> { Age } </td>
             <td> { Occupation } </td>
             <td> { rest['Zip-Code'] } </td>
        </tr>
     )
 })}

6 Comments

This helped, thank you. If you can see any good refactorings in my updated question code ill accept your.
This is much neater looking, but it does not work with the object structure I posted. Object.values(res.data) looks to be flattening all the data received into an array of single characters.
@Kickaha - If an object has 4 key value pair as per the example, Object.values will create an array of 4 objects with each object having the said properties.
Yes that's correct, I checked and my res.data is a string so needed to be parsed with this.setState({ users: Object.values(JSON.parse(res.data))}); ... but the result raises "TypeError: Invalid attempt to destructure non-iterable instance". it seems to be a lot of data mangling to change the response string into an iterable. There must be something simple I am missing. btw, thanks for trying to help. The type of the state is object even though its an array of objects ... sigh ..
I'll update my question a little, thanks for the help. If you can see anything I'm obviously missing please comment again. (even though you've already won the internet today) ;)
|
1

You can use the Object.keys() method to iterate over object keys.

So you can do something similar to this:

Object.keys(res.data).map(id => res.data[id]) which will be evaluated to an array of values.

If you don't care about your keys at all, you can use Object.values() method

1 Comment

This helped, thank you. If you can see any good refactorings in my updated question code ill accept your.

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.