I am facing the issue in my react application.
TypeError: Cannot read properties of undefined (reading 'requestContent')
I am using commercejs in my application. The code points to isEmpty=!cart.line_items.length;. When checked it shows the proper value. Furthermore, I have noticed that the Api returns NULL array twice and populated array the third time. Why is it so? Anyone there to help me sort this issue?
Cart.jsx
import React from "react";
import { Container, Typography, Button, Grid } from "@material-ui/core";
import useStyles from "./CartStyles";
const Cart = ({ cart }) => {
const classes = useStyles();
console.log("CART ",cart.line_items);
const isEmpty = !cart.line_items.length;
const EmptyCart = () => {
<Typography variant="subtitle1">
You donot have any item in your shopping cart. Start adding some of the
items in your shopping cart.
</Typography>;
};
const FilledCart = () => {
<>
<Grid container spacing={3}>
{cart.line_items.map((item) => (
<Grid item xs={12} sm={4} key={item.id}>
<div>{item.name}</div>
</Grid>
))}
<div className={classes.cartDetails}>
<Typography variant="h4">
Subtotal: {cart.subtotal.formatted_With_symbol}
<div>
<Button
className={classes.emptyButton}
size="large"
type="button"
variant="contained"
color="secondary"
>
Empty Cart
</Button>
<Button
className={classes.checkoutButton}
size="large"
type="button"
variant="contained"
color="primary"
>
Checkout
</Button>
</div>
</Typography>
</div>
</Grid>
</>;
};
return (
<Container>
<div className={classes.toolbar} />
<Typography className={classes.title} variant="h3">
Your Shopping Cart
</Typography>
{isEmpty ? <EmptyCart /> : <FilledCart />}
</Container>
);
};
export default Cart;
App.js
import React, { useState, useEffect } from "react";
// import Products from "./components/Products/Products";
// import Navbar from "./components/Navbar/Navbar";\
import { commerce } from "./lib/commerce";
import { Products, Navbar, Cart } from './components';
const App = () => {
const [products, setProducts] = useState([]);
const [cart, setCart] = useState({});
const fetchProducts = async() => {
// call the product api from commerce js
const { data } = await commerce.products.list();
// populates the products
setProducts(data);
}
//get element of cart
const fetchCart = async() => {
const cartItems = await commerce.cart.retrieve();
setCart(cartItems);
}
const handleAddToCart = async(productId, quantity) => {
const itemsInCart = await commerce.cart.add(productId, quantity);
setCart(itemsInCart.cart);
}
useEffect(() => {
//Calling of methods which we want to call on load of component
fetchProducts();
fetchCart();
}, []);
// empty array is given so that it makes a call as soon as component is loaded.
console.log(cart);
return ( <
div >
<
Navbar totalItems = { cart.total_items }
/ > <
Cart cart = { cart }
/> < /
div >
);
};
export default App;
The issue is caused by your initial cart
state in App
:
const [cart, setCart] = useState({});
It's an empty object ({}
) and passed on to the Cart
component that then assumes it has a line_items
property.
const isEmpty = !cart.line_items.length;
Since cart.line_items
is undefined an error is thrown when you then attempt to reference the length
property.
Use an Optional Chaining operator to guard the null access.
const isEmpty = !cart.line_items?.length;
Or guard clause/null check
const isEmpty = !(cart.line_items && cart.line_items.length);
Furthermore, I have noticed that the Api returns NULL array twice and populated array the third time. Why is it so? Anyone there to help me sort this issue?
This is likely a combination of the console.log("CART ",cart.line_items);
in the function component body as an unintentional side-effect and the app being rendered into a React.StrictMode
component that intentionally double invokes certain functions and component methods twice as a way to help you detect unintentional side-effects.
Detecting unexpected side effects
Strict mode can’t automatically detect side effects for you, but it can help you spot them by making them a little more deterministic. This is done by intentionally double-invoking the following functions:
- Class component
constructor
,render
, andshouldComponentUpdate
methods- Class component static
getDerivedStateFromProps
method- Function component bodies
- State updater functions (the first argument to
setState
)- Functions passed to
useState
,useMemo
, oruseReducer