1 year ago
#351022
mattangel
Getting an error titled "Uncaught TypeError: Cannot read properties of undefined (reading 'cartFoodItems')" when clicking on my cart button
I am working on a food app that adds items to a cart then calculates the total amount. I am trying to implement a reducer as opposed to having multiple instances of state hooks and I am running into this error when trying to click open my cart modal.
I know the items are being added successfully to the cart because when I add them, then inspect in the console and remove the "display: none " property from my modal and see the added food items there. For some reason its specifically when I click my cart to see the modal is when I receive the error.
The error message is saying the error is located in my app.js file where I assign define the cartFoods prop to my Cartmodal component
App.js Component
import logo from "./logo.svg";
import "./App.css";
import NavHeader from "./NavHeader";
import { useState, useEffect, useReducer } from "react";
import FoodList from "./FoodList";
import CartModal from "./CartModal";
import "animate.css";
function App() {
const [foods, setFoods] = useState([
{
food: "sushi roll",
description: "fresh tuna topped with eel sauce and avocado",
price: "14.99",
quantity: 1,
},
{
food: "pizza",
description: "baked to a crisp with mozarrella, basil and tomato sauce",
price: "9.99",
quantity: 1,
},
{
food: "special fried rice",
description: "cooked with onions , shrimp , chicken",
price: "19.99",
quantity: 1,
},
{
food: "tacos",
description:
"choice of either ,shrimp , chicken, or steak, topped with pico de gallo",
price: "15.99",
quantity: 1,
},
]);
const [totalFoodAmount, setTotalFoodAmount] = useState(0);
// const [modalDisplay, setModalDisplay] = useState("none");
const [totalPrice, setTotalPrice] = useState(0);
const [cartFoods, setCartFoods] = useState([]);
const [cartItem, setCartItem] = useState({});
const [modalDisplay, setModalDisplay] = useState("none");
const [amountValue, setAmountValue] = useState(0);
function foodReducer(state, action) {
if (action.type === "ADD_CART_ITEMS") {
return { cartFoodItems: state.cartFoodItems.concat(action.val) };
}
}
const [foodState, dispatch] = useReducer(foodReducer, {
modalDisplay: "none",
totalFoodPrice: 0,
cartFoodItems: [],
});
function setDisplay() {
dispatch({ type: "ADD_MODAL_DISPLAY" });
setModalDisplay("flex");
}
function removeModal() {
dispatch({ type: "REMOVE_MODAL_DISPLAY" });
setModalDisplay("none");
}
function setQuantity(e) {
console.log(e.target.value);
setAmountValue(e.target.value);
}
function addFood(food) {
console.log(food);
let newFoodItem = { ...food, quantity: amountValue };
// setCartFoods((prevState) => cartFoods.concat(newFoodItem));
dispatch({ type: "ADD_CART_ITEMS", val: newFoodItem });
// ask slavo specific question on why state doesnt update right away when you console.log(cartFoods) inside the function
}
useEffect(() => {
let total = foodState.cartFoodItems.reduce(function (a, b) {
return a + Number(b.quantity);
}, 0);
setTotalFoodAmount(total);
foodState.cartFoodItems.map((food) =>
setTotalPrice(totalPrice + food.price * food.quantity)
);
}, [foodState]);
return (
<div className="App">
<NavHeader cartQuantity={totalFoodAmount} setDisplay={setDisplay} />
<FoodList foodList={foods} addFood={addFood} setAmount={setQuantity} />
<CartModal
cartFoods={foodState.cartFoodItems}
display={modalDisplay}
closeModal={removeModal}
totalPrice={totalPrice}
/>
</div>
);
}
export default App;
Cart.js component
import React from "react";
export default function Cart(props) {
return (
<div
style={{
display: "flex",
marginRight: "35px",
border: "1px solid lightgray",
padding: "5px",
borderRadius: "5px",
margin: "10px",
}}
className="cart-section"
onClick={props.setDisplay}
>
<div style={{ marginRight: "20px" }}>
<h4>Your Cart</h4>
</div>
<div style={{ position: "relative", top: "0vh" }}>
<h4>Quantity: {props.cartQuantity}</h4>
</div>
</div>
);
}
CartModal.js
import React from "react";
import "animate.css";
import { CSSTransition } from "react-transition-group";
export default function CartModal(props) {
return (
<div
style={{
background: "#000000a6",
width: "100vw",
height: "100vh",
position: "fixed",
top: "0",
left: "0",
overflow: "scroll",
display: props.display,
justifyContent: "center",
alignItems: "center",
}}
>
<div
style={{
background: "white",
padding: "30px",
minHeight: "60vh",
minWidth: "75vw",
borderRadius: "10px",
}}
className="cart-modal"
>
<div style={{ display: "flex", justifyContent: "flex-end" }}>
<h3 onClick={props.closeModal}>x</h3>
</div>
<h4 style={{ textAlign: "center" }}>Your Cart</h4>
{props.cartFoods.length === 0 ? (
<h1>There are no Items in your cart</h1>
) : (
props.cartFoods.map((food, index) => (
<div
style={{
display: "flex",
justifyContent: "space-between",
borderBottom: "2px solid lightgray",
}}
key={index}
>
<div style={{ width: "10vh" }}>
<h3>{food.food}</h3>
<p>{food.price}</p>
<p>Quantity: {food.quantity}</p>
</div>
<div style={{ display: "flex" }}>
<button style={{ margin: "10px", maxHeight: "20px" }}>-</button>
<button style={{ margin: "10px", maxHeight: "20px" }}>+</button>
</div>
</div>
))
)}
<h2>Price: ${props.totalPrice}</h2>
</div>
</div>
);
}
reactjs
react-hooks
components
state
use-reducer
0 Answers
Your Answer