0

I created a React App with AXIOS. I need to get some JSON data from back end and change the State with that data. When I get the object and mapping to my state, the state is only setting for the last element of the object. So I can only see the last element in the state. How I can get all the elements to the state?

My API call is as follows

API.post('viewallusers', [], config)
      .then(({ data }) => {
        const allUsers = data.response.AllUsers;
        allUsers
          .map(user => {
            return (
              this.setState({
                data: [
                  createData(
                    user.name,
                    user.id,
                    user.email
                  )
                ]
              })
            )
          })
      })
      .catch((err) => {
        console.log("AXIOS ERROR: ", err);
      })

JSON data:

{response :
  {AllUsers :
    0 : {name: "Amy", id: 1, email: "myEmail1"},
    1 : {name: "Doris", id: 2, email: "myEmail2"},
    2 : {name: "Jase", id: 3, email: "myEmail3"}
  }
}

I expect the the state "data" is to be set as follows:

data : [
  createData("Amy",1,"myEmail1"),
  createData("Doris",2,"myEmail2"),
  createData("Jase",3,"myEmail3")
]

But the actual state after getting the JSON data is

data : [
  createData("Jase",3,"myEmail3")
]

How can I solve this?

2 Answers 2

1

You need to first map the data then set entire state.

API.post('viewallusers', [], config)
  .then(({ data }) => {
    this.setState({
      data: data.response.AllUsers.map(user => (createData(user.name, user.id, user.email)))
    })
  })

Or use callback version of setState and manually merge state.data (NOT recommended in this particular case)

API.post('viewallusers', [], config)
  .then(({ data }) => {
    data.response.AllUsers.forEach(user => {
      this.setState(prev =>
        ({...prev, data: [prev.data, createData(user.name, user.id, user.email)]})
      )
    })
  })
Sign up to request clarification or add additional context in comments.

Comments

1

It probably happens because setState doesn't do a deep merge. So if you have in state

state = {
    key1: 123,
    key2: {
        test1: 1,
        test2: 2

    }

}

And you do

this.setState({
    key2: {
        test1: 4
    }

})

You will end up with

state = {
    key1: 123,
    key2: {
        test1: 4
    }

} 

You have to do instead:

this.setState((ps) => ({
    key2: {
        ...ps.key2,
        test1: 4
    }

}));

Similar approach works if value for key2 is array. Or alternatively you can first map all the data and then do a setState as suggested in other answer.

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.