Bodrov
Bodrov

Reputation: 867

React - Rendering an array of objects using Map

I'm trying to render an array of objects using Map and so far I've only been able to render the first item to the browser.

I figured something's up with my .map function, but I don't know enough about React and JS to pinpoint the problem.

Here's my App.js file:

// import stuff is here

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      items: []
    };
    this.componentWillMount = this.componentWillMount.bind(this);
  }

  componentWillMount() {
    fetch('THE-JSON-URL-IS-HERE')
    .then(res => res.json())
    .then(data => {
      this.setState({ items: data });
    });

 render() {

const { items } = this.state;

return (
  <div className="App">

    { items.map((item, num) => {
        return (
          <div className="people">

            <div className="elem">
              <p key={num}>{item.elems}</p>   
            </div>     

              <p key={num}><strong>{item.name}</strong></p>
              <p key={num}><small>{item.title}</small></p>             

            <div className="hidden">
              <p key={num}><small>{item.email}</small></p>
              <p key={num}><small><strong>Office: </strong>{item.office}</small></p>
            </div>
            {/* <p>{item.manager}</p> */}
          </div>

        );
    })}        
  </div>
    );
  }
}

export default App;

And here's a sample of the JSON file:

[
  {
    "elems": "Pr",
    "name": "Abby Langdale",
    "title": "President",
    "email": "[email protected]",
    "office": "Javanrud",
    "manager": [
      {
        "elems": "Vp",
        "name": "Johnnie Mouncey",
        "title": "Vice President",
        "email": "[email protected]",
        "office": "Canto",
        "manager": [
          {
            "elems": "Vp",
            "name": "Concordia Burgwyn",
            "title": "VP Quality Control",
            "email": "[email protected]",
            "office": "Zhoukou",
            "manager": [
              {
                "elems": "En",
                "name": "Prissie Sainsberry",
                "title": "Web Developer IV",
                "email": "[email protected]",
                "office": "Tugu",
                "manager": null
              },

etc. Abby's info is all that I've rendered.

Upvotes: 0

Views: 2971

Answers (2)

Steve Conrad
Steve Conrad

Reputation: 341

Try flattening the array first. You would need to know the maximum number of levels that the array will have. Once it's flattened, you can use your map function:

const flatItems = items.flat(3);    // flatten up to 3 levels
items.map((item, num) => {
        return ( <render your div> );
}

Upvotes: 1

Jesse Martin
Jesse Martin

Reputation: 46

Since you're nesting arrays and objects into your first array element, the length of items is 1 and the only element is the Abby element with the rest of the data nested inside of it. To map through all of the elements, items should look like this array:

[
  {
    "elems": "Pr",
    "name": "Abby Langdale",
    "title": "President",
    "email": "[email protected]",
    "office": "Javanrud",
    "manager": ""
  },
  {
    "elems": "Vp",
    "name": "Johnnie Mouncey",
    "title": "Vice President",
    "email": "[email protected]",
    "office": "Canto",
    "manager": ""
  },
  {
    "elems": "Vp",
    "name": "Concordia Burgwyn",
    "title": "VP Quality Control",
    "email": "[email protected]",
    "office": "Zhoukou",
    "manager": ""
  },
  {
    "elems": "En",
    "name": "Prissie Sainsberry",
    "title": "Web Developer IV",
    "email": "[email protected]",
    "office": "Tugu",
    "manager": null
  }
]

If you need to maintain the relationship of managers, you can add an id to each object and reference it from another object.

  [
      {
        "elems": "Pr",
        "name": "Abby Langdale",
        "title": "President",
        "email": "[email protected]",
        "office": "Javanrud",
        "manager": "",
        "id" : 1
      },
      {
        "elems": "Vp",
        "name": "Johnnie Mouncey",
        "title": "Vice President",
        "email": "[email protected]",
        "office": "Canto",
        "manager": 1
      },
      ...
]

You would need a filter helper function to do the correct lookup for a manager's name but it should work.

Upvotes: 1

Related Questions