sanjay srinivasa
sanjay srinivasa

Reputation: 41

Map over nested array of objects

I am trying to map over array of objects which each array contains another nested array of objects. However, the map does not work on the nested array. How do i map over the contents of the nested array?

data structure for nested array of objects looks like this:

const items = [
  {
    page_num: 1,
    status: "PROCESSED",
    table_text_data:[
        {bottom:58, height:60, left:60, right:67, text:"recorded"},
        {bottom:75, height:67, left:50, right:60, text:"symbolic"},
        {bottom:80, height:80, left:77, right:89, text:"fever"},
    ]
  }
];

map for page_num and status looks like this:

{this.props.items.map(item =>{ 
   return (
        <ul><li> page_num={item.page_num} </li>
         <li> status:{item.status}</li>
          {item.table_text_data.map((c,i)=>( 
           <ul><li>bottom={c.bottom}</li>
           <li>height={c.height}</li>
           <li>left={c.right}</li>
           <li>right={c.left}</li>
           <li>text={c.text}</li></ul>  
         ))}
        </ul>
)})}

page_num and status works fine but not for table_text_data. how should i map through it?

screenshot of the warning i'm getting as well: https://i.sstatic.net/sqREQ.png

Any help would be much appreciated. Thank you

Upvotes: 0

Views: 1275

Answers (3)

Sam Apostel
Sam Apostel

Reputation: 603

the error you give is has the answer in it.

Each child in a list should have a unique key prop

you're already halfway there by extracting the index that holds the nested object. Now you only have to add the property key={I} to your ul

const items = [
  {
    page_num: 1,
    status: "PROCESSED",
    table_text_data:[
        {bottom:58, height:60, left:60, right:67, text:"recorded"},
        {bottom:75, height:67, left:50, right:60, text:"symbolic"},
        {bottom:80, height:80, left:77, right:89, text:"fever"},
    ]
  },
  {
    page_num: 2,
    status: "PROCESSED",
    table_text_data:[
        {bottom:58, height:60, left:60, right:67, text:"recorded"},
        {bottom:75, height:67, left:50, right:60, text:"symbolic"},
        {bottom:80, height:80, left:77, right:89, text:"fever"},
    ]
  }
];
    
const ItemDisplay = (props) => (
  <React.Fragment>
    {props.items.map(item => (
      <ul key={item.page_num}>
        <li>page_num={item.page_num}</li>
        <li>status={item.status}</li>
        {item.table_text_data.map((c,i) => ( 
          <ul key={i}>
            <li>bottom={c.bottom}</li>
            <li>height={c.height}</li>
            <li>left={c.right}</li>
            <li>right={c.left}</li>
            <li>text={c.text}</li>
          </ul>  
        ))}
      </ul>
    ))}
  </React.Fragment>
  );

ReactDOM.render(
  <ItemDisplay items={items} />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Upvotes: 0

wangdev87
wangdev87

Reputation: 8751

Why don't you use re-use array map?

{this.props.items.map((item, i) =>{ 
   return (
        <ul key={'parent' + i}><li> page_num={item.page_num} </li>
         <li> status:{item.status}</li>
          {item.table_text_data.map((c,j)=>( 
           <li  key={'child' + j}>
           <ul><li>bottom={c.bottom}</li>
           <li>height={c.height}</li>
           <li>left={c.right}</li>
           <li>right={c.left}</li>
           <li>text={c.text}</li></ul>
           </li>
         ))}
        </ul>
)})}

Upvotes: 1

sharun k k
sharun k k

Reputation: 467

you can use nested map function to acces the files. but you need to speciy that nested map() should work only for table_text_data property,other wise your parent map function will check for the contents inside table_text_data you can rewrite the code like

{this.props.items.map(item =>{ 
   return(
<ul>
<li> page_num={item.page_num} </li>
<li> status:{item.status}</li>
</ul>
   if(item ==='table_text_data'){
      {item.table_text_data.map((c,i)=>( 
          return (
 <ul><li>bottom={c.bottom}</li>
           <li>height={c.height}</li>
           <li>left={c.right}</li>
           <li>right={c.left}</li>
           <li>text={c.text}</li></ul> 
))
}
)}
        </ul>
)})}

Upvotes: 0

Related Questions