0

how to map subarray in react based on key of parent array? enter image description here

I have tried mapping by id key of main array to map elements of dish_count array

<TableCell  align="left">
       {this.state.persons.map((items,name) => 
             <div key={this.state.persons.id}> 
    {(typeof(items.dish_count)=="object")? (<div>
              { items.dish_count.map((subdata) =>
                                    <table>
                                       <td >
                                         {subdata.meal_type}
                                         </td>
                                         </table>
                                  )
                                      }
                               </div>): (null)}</div>)}



                               </TableCell>
                               <TableCell align="left">    {this.state.persons.map((items,name) => 
                                <div key={this.state.persons.id} >{(typeof(items.dish_count)=="object")? (<div>
                                      {
                                       items.dish_count.map((subdata) =>

                                       <table>
                                       <td >
                                         {subdata.dish_count}
                                         </td>
                                         </table>
                                       )
                                      }
                               </div>): (null)}</div>)}</TableCell>

i want to map subarray dish_count by key id of parent array .I am able to map but the mapping is multiple and is not exclusive by parent array key.dish_count is the subarray of package array

persons array

 "data": [
            {
                "id": 1,
                "name": "Gold",
                "dish_count": [
                    {
                        "dish_count": 4,
                        "meal_type": "Starters"
                    },
                    {
                        "dish_count": 4,
                        "meal_type": "Main Course"
                    },
                    {
                        "dish_count": 4,
                        "meal_type": "Dessert"
                    },
                    {
                        "dish_count": 4,
                        "meal_type": "Lunch"
                    }
                ]
            },
            {
                "id": 2,
                "name": "Basic",
                "dish_count": [
                    {
                        "dish_count": 2,
                        "meal_type": "Starters"
                    },
                    {
                        "dish_count": 2,
                        "meal_type": "Main Course"
                    },
                    {
                        "dish_count": 2,
                        "meal_type": "Dessert"
                    },
                    {
                        "dish_count": 2,
                        "meal_type": "Lunch"
                    }
                ]
            }
]

I want Meal Type No of Dishes Gold Starters 4 Main Course 4 Desert 4 Lunch 4 Basic Starters 2 Main Course 2 Desert 2 Lunch 2

3
  • Can you show us the code for persons and how you expect your data to look like. Commented Aug 16, 2019 at 11:42
  • Yes i can show you the code for persons Commented Aug 16, 2019 at 12:24
  • You set persons to be an empty string, that does not work with map. The console.log will not display the persons because setState is async. The state will be set later, use the callback of setState to get the persons: this.setState({persons:res.data.data.data}, () => console.log('package',this.state.persons) ); Commented Aug 16, 2019 at 12:30

1 Answer 1

1

You have a few problems in your code:

  1. this.state({persons:''});: This will set the initial persons to be an empty string and will fail with map.
  2. console.log('package',this.state.persons): setState is async and the console.log will not print the desired state but the previous state. Use the callback of setState as second parameter to access the new state:

    this.setState({persons:res.data.data.data}, () => console.log('package',this.state.persons) );
    
  3. this.state.persons.map((items, name) =>: The map function will provide different parameters: the first is the person and the second is the index of that person within the array.

  4. div key = {this.state.persons.id}: since persons is an array, the key will be undefined. If you use the map function correctly, you can use person.id.

When you fixed these problems, the code should work as expected.

To only show the expected dishes per person and not to print the duplication you have to write it like this:

class Table extends React.Component {       
    render() {
        return <table>
            <thead>
                <tr>
                    <td>ID</td>
                    <td>Name</td>
                    <td>Meal Type</td>
                    <td>Number of Dishes</td>
                </tr>
            </thead>
            <tbody>
                {this.state.persons.map(person =>
                    <tr>
                        <td>{person.id}</td>
                        <td>{person.name}</td>
                        <td>
                            <table>
                              <tbody>
                                   {person.dish_count.map(dish => <tr>
                                         <td>{dish.meal_type}</td>
                                     </tr>
                                     )}
                              </tbody>
                        </table>
                    </td>
                    <td>
                        <table>
                          <tbody>
                              {person.dish_count.map(dish => <tr >
                                  <td>{dish.dish_count}</td>
                               </tr>
                               )}
                          </tbody>
                        </table>
                    </td>
                </tr>
            )
            }
        </tbody>
    </table >
    }
}

By not iterating over the person for each sub-table, you can remove the duplicated data.

codepen

Hope this helps.

Sign up to request clarification or add additional context in comments.

13 Comments

any other techniques for this problem
I see you fixed your code. Can you show us how persons looks and what exactly the current error is?
key={this.state.persons.id} wont work because this.state.persons is an array, use items.id.
I tried the above thing but the mapping is multiple times the data.
How does persons look like pls. Can you post the array?
|

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.