Search code examples
reactjslodash

groupBy json data then map in React component


I'm trying to group my JSON data so that all staff in the same 'department' are in an object together. Then I want to map through the data so I can display it on my webpage.

At the moment i'm getting the error 'cannot read property of map undefined'

my JSON data:

people:[  
  {  
     id:"a0bef",
     title:"cleaner",
     department:"facilities",

  },
  {  
     id:"a0beg",
     title:"maintenance",
     department:"facilities",

  },
  {  
     id:"a0beh",
     title:"cleaner",
     department:"facilities",

  },
  {  
     id:"a0bei",
     title:"chef",
     department:"kitchen",

  },
  {  
     id:"a0bej",
     title:"waitress",
     department:"kitchen",

  }
]

which I would like to look like:

people:[  
  "facilities":[  
     {  
        id:"a0bef",
        title:"cleaner"
     },
     {  
        id:"a0beg",
        title:"maintenance"
     },
     {  
        id:"a0beh",
        title:"cleaner"
     }
  ],
  "kitchen":[  
     {  
        id:"a0bei",
        title:"chef"
     },
     {  
        id:"a0bej",
        title:"waitress"
     }
  ]
]

this is what I have tried:

import React from 'react'
import _ from 'lodash'

class PeopleList extends React.Component {
  constructor (props) {
    super(props)
  }

  render () {
    const { peoplelist } = this.props
    const people = _.groupBy(peoplelist, 'department')
    return (
      <div>
        { Object.people.map(function (person, key) {
          return (
            <div className='row' key={key}>
              <div className='col-md-6'>{person.department}</div>
              <div className='col-md-4'>{person.title}</div>
            </div>
          )
        }) }
      </div>
    )
  }
}



export default PeopleList

Solution

  • You are getting this error because Object.people is not a valid syntax.

    people after const people = _.groupBy(peoplelist, 'department') will be an Object. You need to get all the values of the object (using Object.values(people)); which will give you an array of person. Then, map through that array to get the desired output.

    The function will be modified to

    Object.values(people).map(function (deptArray) { 
        return deptArray.map(function (person) {
          return (
            <div className='row' key={some-unique-key}>
              <div className='col-md-6'>{person.department}</div>
              <div className='col-md-4'>{person.title}</div>
            </div>
          )            
        })
    })
    

    Note: In the above case you won't be able to use array indexes as the key, because the keys will be repeated (and so, I have removed it from my solution).

    Hope it helps. Revert for any clarifications/doubts.