4

I'm using axios and redux for an api request that returns a response.data which is an array of objects.

My action reducer is as follows:

export default function(state = [], action) {
  switch (action.type) {
     case FETCH_USERS:
         console.log(action.payload.data)
         return { ...state, users: action.payload.data };
       }
  return state;
}

The console.log returns this in the chrome console

 [object, object]

My problem arises to how I can map the data of objects. I tried the following where I mapped the array. (Users is the prop of the object array.)

  ....
 {this.props.users.map(this.renderUser)}
 ...

 renderUser(user) {
  return (
    <tr>
      <td> {user.contact_name}</td>
      <td> {user.contact_email}</td>
    </tr>
  );
}

When I use the React console to check my props i get the following:

users: {...}
   users: 
      0:{...}
      1:{...}

I'm not sure how to map the objects to html. Would it be better if I converted it to string and mapped that? My mapping appears blank.

5
  • You didn't say it but what's your problem? your mapping doesn't work? Commented Apr 29, 2016 at 3:48
  • @QoP sorry, I edited my post. My mapping does not work and appears blank. Commented Apr 29, 2016 at 3:51
  • how are you mapping your redux state to your component? Commented Apr 29, 2016 at 3:52
  • function mapStateToProps(state) { return { users: state.users }; } export default connect(mapStateToProps, actions)(Users); I'm using the React plugin and the props seem to be present so I think it might be a mapping issue Commented Apr 29, 2016 at 3:54
  • check the answer :-P Commented Apr 29, 2016 at 3:57

2 Answers 2

3

Your problem is that your state has the same name as your array and that is confusing you.

Your users reducer is

const initialState = {
   ....
   users : []
}

when you map it to your props using the name "users" what you got is

this.props.users = initialState

so in order to access to users you need to use

this.props.users.users

That said, the way to access to your users is like this.

  ....
 {this.props.users.users.map(this.renderUser)}
 ...

 renderUser(user) {
  return (
    <tr>
      <td> {user.contact_name}</td>
      <td> {user.contact_email}</td>
    </tr>
  );
}
Sign up to request clarification or add additional context in comments.

6 Comments

that makes a lot of sense, however when I do this.props.users.users.map I get an error Uncaught TypeError: Cannot read property 'users' of undefined. There's probably something else that's causing this issue but thanks for the suggestion
do you have an initial state?
Would the export default function(state = [], action) from the reducer be the initial state?
yeah but that doesn't contain users, state = { users : []} would be a better idea. You are probably accessing to your users.users before fetching the data and users doesnt exist, thats why you got that error
seems like there's a better underlying mapping fix. I'm not sure what it is though. I've got the same thing going on and instead of checking if this.props.users.users exist I'd rather just be able to always rely this.props.users
|
1

In store, if your users is a nested object, you can fix this in mapStateToProps.
It not only tells react/redux which data you want but also,
how to transform/map said data from the way it is stored in the redux store,
to how you'd like it to appear on props:

mapStateToProps( store ){
  return {
    users: store.users.users,
  }
}

Now, within your component, you can access and map over your users (array) as this.props.users, rather than this.props.users.users.


Another thing that you could look at is how data is being pulled from the API and stored into the redux store.
If your API is giving you nested data (one route on an API I was using, oddly did this).

In that case.. In order to have your props/state/store object in the expected format, change this line:

return { ...state, users: action.payload.data };

to this:

return { ...state, users: action.payload.data.users };

The full function will look like this:

export default function(state = [], action) {
  switch (action.type) {
     case FETCH_USERS:
         console.log(action.payload.data)
         return { ...state, users: action.payload.data.users };
       }
  return state;
}

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.