Ece Nur Battal
Ece Nur Battal

Reputation: 11

TypeError: Cannot read property 'name' of undefined in ReactJS

I'm trying to make a dynamic burger builder in ReactJS. As soon as the homepage opens, I get an error like this:

TypeError: Cannot read property 'name' of undefined
IngredientsMenuItem
/src/components/IngredientsMenu/IngredientsMenuItem.js:18
  15 | return (
  16 |     <ItemWrapper>
  17 |         <ItemContent>
> 18 |             <h3>{item.ingredient.name}</h3>
     | ^  19 |             <h4>{item.ingredient.price}</h4>
  20 |                 <Counter
  21 |                     value={item.qty}

I keep my burger in a context.

My ingredients file:

export const ingredients= [
    {
        name:"salad",
        price:0.5,
    },
    {
        name:"cheese",
        price:0.4,
    },
    {
        name:"meat",
        price:1.3,
    },
];

My home page:

const Home = () => {
    const {burger,updateBurger} = useContext(BurgerContext);

    return (
        <div>
            {!burger.length && updateBurger(buildBurger(ingredients))}
            <Burger/>
            <IngredientsMenu
                ingredients={ingredients}
            />
        </div>
    )
}

export default Home

My buildBurger function:

export const buildBurger = (ingredients) => {
    return [
        ingredients.map((ingredient) => (
            {
                qty:0,
                ingredient: ingredient
            }
        ))
    ]
} 

I did this to create a template for ingredients with values ​​0 in the initial state.

My IngredientsMenu:

const IngredientsMenu = ({ingredients}) => {
    const {burger, updateBurger} = useContext(BurgerContext);
    return (
        <>
        
        <Wrapper>
            {burger.map((item) => (
                <IngredientsMenuItem
                    item={item}
                />
            ))}
        </Wrapper>
        </>
    )
}

export default IngredientsMenu

My IngredientsMenuItem:

const IngredientsMenuItem = ({item) => {
    const {burger, updateBurger} = useContext(BurgerContext);
    const handleIncrement = (burgerItem) => {
        
    }
    const handleDecrement = (burgerItem) => {
        
    }
    
    return (
        <ItemWrapper>
            <ItemContent>
                <h3>{item.ingredient.name}</h3>
                <h4>{item.ingredient.price}</h4>
                    <Counter
                        value={item.qty}
                        onIncrement={() => handleIncrement(item)}
                        onDecrement={() => handleDecrement(item)}
                    />
            </ItemContent>
        </ItemWrapper>
    )
}

export default IngredientsMenuItem

I couldn't see where my fault was. Is there anyone who can help?

Upvotes: 0

Views: 119

Answers (1)

Sergio Moura
Sergio Moura

Reputation: 4942

On your component IngredientsMenuItem, the item prop is probably null or undefined.

Consider adding a console.log instruction inside your component to see what's exactly there.

If you want your code to "never break", you can check if the contents are there, and if they are not, revert to an empty object, like so:

const IngredientsMenuItem = ({item) => {
    const {burger, updateBurger} = useContext(BurgerContext);
    const handleIncrement = (burgerItem) => {
        
    }
    const handleDecrement = (burgerItem) => {
        
    }

    const ingredient = (item && item.ingredient) || {};
    // this can be replaced to a shorter version if you support the `?.` operator:
    // const ingredient = item?.ingredient || {};

    const qty = (item && item.qty) || 0;
    
    return (
        <ItemWrapper>
            <ItemContent>
                <h3>{ingredient.name}</h3>
                <h4>{ingredient.price}</h4>
                    <Counter
                        value={qty}
                        onIncrement={() => handleIncrement(item)}
                        onDecrement={() => handleDecrement(item)}
                    />
            </ItemContent>
        </ItemWrapper>
    )
}

Upvotes: 1

Related Questions