I have used React-Query many times, but when I return an API call from Strapi, I receive the error:
TypeError: Cannot read properties of undefined (reading 'map')
It's basically a simple function call as follows:
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} />
));
}
This is the JSON format of the strapi return:
{
"data": [
{
"id": 1,
"attributes": {
"name": "The Contemplation of Union",
"description_long": "The graphite pencil work that started it all. Captured second place at the prestigious Brownlee O. Curry Art Competition.",
"price": 399,
"createdAt": "2022-05-01T02:07:51.795Z",
"updatedAt": "2022-05-01T02:07:54.191Z",
"publishedAt": "2022-05-01T02:07:54.189Z"
}
},
{
"id": 2,
"attributes": {
"name": "Homage to Dali",
"description_long": "The seminal dedication and homage to the great Salvador Dali. Here is the Soft Construction with Boiled Beans (Premonition of Spanish Civil War)",
"price": 599,
"createdAt": "2022-05-01T02:08:52.013Z",
"updatedAt": "2022-05-01T02:08:53.458Z",
"publishedAt": "2022-05-01T02:08:53.456Z"
}
},
{
"id": 3,
"attributes": {
"name": "Still Life with Melon",
"description_long": "Still life painted alla prima with juicy Melon and found objects",
"price": 399,
"createdAt": "2022-05-01T02:09:49.536Z",
"updatedAt": "2022-05-01T02:09:50.840Z",
"publishedAt": "2022-05-01T02:09:50.839Z"
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 3
}
}
}
When running this I get back the request as a 200, so the data and the fetch happens. I don't think I am referring to the data the appropriate way.
CodePudding user response:
I'm not familiar with React-Query, but what i noticed is that the JSON response doesn't have a property products, only data.
So the react code would need to look like this:
export default function ProductList() {
const { data: products, isLoading } = useQuery('Products', () =>
axios('/api/products').then((res) => res.data)
);
if (isLoading) return <LoadingSpinner />
return products.map((product) => (
<ProductItem key={product.id} product={product} />
));
}
Hope this helps.
CodePudding user response:
Why don't you render a dummy button like that, just click to console log the "products" to make sure they are in the format that you want.
export default function ProductList() {
const { data: products, isLoading } = useQuery('Products', () =>
axios('/api/products').then((res) => res.data)
);
if (isLoading) return <LoadingSpinner />
return
<div>
<button onClick={() => console.log("products", products)}>Click to see products</button>
{products.data.map((product) => (
<ProductItem key={product.id} product={product} />
))}
</div>
}