Reputation: 61
I am new to react and I am having some trouble mapping nested array of objects in my app as it comes as undefined.
This is my api response which is an array of recipes.
const recipeMock = [
{
"ingredientsInfo": [
{
"ingredientId": {
"_id": "609e1325f5bbf3301d24102c",
"name": "spaghetti squash",
},
"gramsPerIngredient": 301
},
{
"ingredientId": {
"_id": "609e1325f5bbf3301d24102b",
"name": "spaghetti squash",
},
"gramsPerIngredient": 47
},
],
"_id": "609e1326f5bbf3301d241242",
"name": "pain de mie",
"gramsPerRecipe": 223,
"elabTime": 20,
"carbs": 201,
"proteins": 10,
"calories": 605,
"instructions": "hi",
"picture": "https://unsplash.com/photos/ijlUGGnrZsI",
},{...other recipes following same structure
}]
I have created a component which paints each recipe that is the following:
export default function RecipeCard({
recipeId,
recipeName,
ingredientsInfo,
elabTime,
carbs,
proteins,
calories,
instructions,
picture,
addRecipeToUser,
})
which in return renders a card. But trouble comes when mapping ingredientsInfo
as follows:
<div className="recipeCard_ingredients">
<ul className="recipeCard_ingredients_list">
{ingredientsInfo.map((ingredient, index) => (
<li key={index}>
<Link to={`/ingredients/${ingredient.ingredientId.name}`}>
{ingredient.ingredientId.name}
</Link>
<p>{ingredient.gramsPerIngredient} grams</p>
</li>
))}
</ul>
</div>
The console tells me "Cannot read property 'map' of undefined".
Upvotes: 1
Views: 260
Reputation: 765
Firstly, the RecipeCard
function mustn't receive the recipeMock
object as its parameters. In React, function parameters are used to pass props from other components.
Secondly, you have to map over recipeMock
before you can access ingredientsInfo
, since both are arrays. This means you have to nest two map functions like so:
const recipeMock = [
{
ingredientsInfo: [
{
ingredientId: {
_id: "609e1325f5bbf3301d24102c",
name: "spaghetti squash"
},
gramsPerIngredient: 301
},
{
ingredientId: {
_id: "609e1325f5bbf3301d24102b",
name: "spaghetti squash"
},
gramsPerIngredient: 47
}
],
_id: "609e1326f5bbf3301d241242",
}
];
const RecipeCard = () => {
return recipeMock.map(({ ingredientsInfo, _id }) => (
<div key={_id}>
{ingredientsInfo.map(
({ gramsPerIngredient, ingredientId: { _id, name } }) => (
<p key={_id}>
{gramsPerIngredient}, {name}
</p>
)
)}
</div>
));
};
Here's a working demo in CodeSandbox.
Upvotes: 0
Reputation: 85573
Based on the error, and the mock, you have used:
<RecipeCard {...recipeMock} />
Instead of:
<RecipeCard {...recipeMock[0]} />
If you insist to use without index then make sure to map it first and then only map ingredientsInfo
inside of it.
Upvotes: 0
Reputation: 2485
The error Cannot read property 'map' of undefined
will be encountered if there is an error in the ingredientsInfo
or ingredientsInfo
there is no array.
Better put condition to check the the array like:
<div className="recipeCard_ingredients">
<ul className="recipeCard_ingredients_list">
{ingredientsInfo && ingredientsInfo.map((ingredient, index) => (
<li key={index}>
<Link to={`/ingredients/${ingredient.ingredientId.name}`}>
{ingredient.ingredientId.name}
</Link>
<p>{ingredient.gramsPerIngredient} grams</p>
</li>
))}
</ul>
</div>
Upvotes: 1