I am using the react-query package to just return a simple list of products from an api and for some reason it keeps giving this error:
TypeError: Cannot read properties of undefined (reading 'map')
For some reason it doesn't recognize the products object return and won't iterate over them in the map. Very puzzling.
export default function ProductList() {
const { data: products, isLoading } = useQuery('Products', () =>
axios('/api/products').then((res) => res.data.products)
);
if (isLoading) return <LoadingSpinner />
return products.map((product) => (
<ProductItem key={product.id} product={product} />
));
}
function ProductItem({ product }) {
const price = formatProductPrice(product);
return (
<div className="p-4 md:w-1/3">
<div className="h-full border-2 border-gray-800 rounded-lg overflow-hidden">
<Link to={`/${product.id}`}>
<img
className="lg:h-96 md:h-36 w-full object-cover object-center"
src={product.image}
alt={product.name}
/>
</Link>
<div className="p-6">
<h2 className="tracking-widest text-xs title-font font-medium text-gray-500 mb-1">
{product.category}
</h2>
<h1 className="title-font text-lg font-medium text-white mb-3">
{product.name}
</h1>
<p className="leading-relaxed mb-3">{product.description}</p>
<div className="flex items-center flex-wrap ">
<Link to={`/${product.id}`} className="text-indigo-400 inline-flex items-center md:mb-2 lg:mb-0">
See More
<svg
fill="none"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
className="w-4 h-4 ml-2"
viewBox="0 0 24 24"
>
<path d="M5 12h14M12 5l7 7-7 7"></path>
</svg>
</Link>
<span className="text-gray-500 mr-3 inline-flex items-center lg:ml-auto md:ml-0 ml-auto leading-none text-lg pr-3 py-1 border-gray-800 font-bold">
{price}
</span>
</div>
</div>
</div>
</div>
);
}
CodePudding user response:
Thanks everyone for their help. Everyone's answer and suggestion was great and led me to the solution. Shout out goes to Phil to check the API. I was getting a malformed return in the JSON that was causing this
CodePudding user response:
just add default value(empty array) for products in the case the api call fails.
here
const { data: products = [], isLoading } = useQuery('Products', () =>
axios('/api/products').then((res) => res.data.products)
);
or here
return (products || []).map((product) => (
<ProductItem key={product.id} product={product} />
));
this will solve your issue