ryatkins
ryatkins

Reputation: 348

React component returns empty doing foreach on JSON object

I have a JSON object with multiple leves that I'm trying to iterate through to display like this, but I keep getting empty results.

<div>    
Operation
    **Speed: Slow
    **Direction: Forward
    **Status: Moving
</div>
<div>
Detail
**Type: Electric
**Drivetrain: AWD
</div>

JSON object

    "operation": {
        "speed": "slow",
        "direction": "forward",
        "status": "moving"
      },
  "detail": {
    "type": "electric",
    "drivetrain": "AWD"
  }

The following works, but difficult to wrap each level in a DIV

    const Bompush = (obj) => {
        let output = []

        Object.keys(obj).forEach(key => {
            output.push(<div key={key}>{key}</div>)

            Object.keys(obj[key]).forEach (value => {
                output.push(<div key={value}>{value}</div>)

            })
        })

        return output  
}

This is the ideal way I'd like to do this but it returns empty

const Bom = (obj) => {
 return (
    <div className="outerContainer">
        {
            Object.keys(obj).forEach((key, item) => { 
                return (
                    <div className="category" key={key}>{key}
                        {                        
                        Object.keys(obj[key]).forEach (value => { 
                            return (<div className="item" key={value}>{value}</div>); 
                        })
                        }
                    </div>
                );
            })
        }
    </div>
  );  

 }

My React component

  export default class DiplayBom extends React.Component {

    render() {

        return (
        Bom(this.props.myValues)
        )
    }


  }

Upvotes: 0

Views: 236

Answers (1)

Dave Newton
Dave Newton

Reputation: 160251

forEach doesn't collect the results. You want map:

Object.keys(obj[key]).map(value => (
  <div className="item" key={value}>{value}</div>
))

You'd be better off pulling out the inner component (at the very least), because as simple as this is, it's already pretty hard to read. I'd consider restructuring the object, plus you're at the mercy of object property ordering, so you may not always get the results you'd prefer.

There's some refactoring and/or rethinking to be done.


Without deviating much from your original code, and completely untested, I'd probably start thinking more along these lines:

const Item = ({ value, item }) => (
  <div className="item">{value}: {item}</div>
)

const Category = ({ cat, obj }) => {
  return (
    <div className="category">
      {key}

      {Object.keys(obj).map(val => <Item key={val} value={val} item={obj[val]} />)}
    </div>
  )
}

const Bom = obj => (
  <div className="outerContainer">
    {Object.keys(obj).map(cat => <Category key={cat} cat={cat} obj={obj[cat]} />)}
  </div>
)

Upvotes: 2

Related Questions