Please I'm using fetch to get data from an API, but only the JSX return without the products. Api is from: http://fakestoreapi.com/docs
Please my code just returns the JSX without the contents from the API. I tried using the fetch() when I console.log, I see the array of products. My problem is how to output these products from the API.
Please help me debug, I've tried different approaches but I've always been stocked at this point. Thank you.
Product.js file
import React, { useEffect, useState } from "react";
const Products = () => {
const [products, setProducts] = useState([]);
const [loading, setLoading] = useState(false);
const { title, image, price, category } = products;
useEffect(() => {
getProducts();
// eslint-disable-next-line
}, []);
const getProducts = async () => {
setLoading(true);
const res = await fetch("https://fakestoreapi.com/products");
const data = await res.json();
setProducts(data);
setLoading(false);
console.log(data);
};
if (loading) {
return <h4>Loading.....</h4>;
}
return (
<div>
{!loading && products.length === 0 ? (
<p className='center'>No logs to show....</p>
) : (
products.map((product) => (
<div class='card' style={{ width: "18rem" }} key={products.id}>
<img src={image} class='card-img-top' alt='...' />
<div class='card-body'>
<h5 class='card-title'>Card title</h5>
<p class='card-text'>
Some quick example text to build on the card title and make up
the bulk of the card's content.
</p>
</div>
<ul class='list-group list-group-flush'>
<li class='list-group-item'>{title}</li>
<li class='list-group-item'>$ {price}</li>
<li class='list-group-item'>{category}</li>
</ul>
<div class='card-body'>
<a href='#' class='card-link'>
Card link
</a>
<a href='#' class='card-link'>
Another link
</a>
</div>
</div>
))
)}
</div>
);
};
export default Products;
3 answers
-
answered 2022-01-25 09:02
Deknoinarak
I don't know too. But this worked for me.
products.map(({ title, image, price, category }, index) => ( <div key={index} class='card' style={{ width: "18rem" }} key={products.id}> <img src={image} class='card-img-top' alt='...' /> <div class='card-body'> <h5 class='card-title'>Card title</h5> <p class='card-text'> Some quick example text to build on the card title and make up the bulk of the card's content. </p> </div> <ul class='list-group list-group-flush'> <li class='list-group-item'>{title}</li> <li class='list-group-item'>$ {price}</li> <li class='list-group-item'>{category}</li> </ul> <div class='card-body'> <a href='#' class='card-link'> Card link </a> <a href='#' class='card-link'> Another link </a> </div> </div> )) )}
You need to add
{ title, image, price, category }
in the map function. I think it is because the map function doesn't know what is{ title, image, price, category }
variables and you need to add a key every time you use the map function and don't forget to changeclass=
toclassName
. -
answered 2022-01-25 09:04
Bhumik
You can simply use
product?.title ,product?.price,product?.category
to access individual fields. This approach is better than the other as you will not get an error for the field that is not in the API. -
answered 2022-01-25 09:09
a_dahlin
You have to first destructure the properties that you are trying to use in you JSX (title, price, category), then you can show them.
products.map((product) => { const { title, price, category } = product; return (****your JSX goes here***)})
do you know?
how many words do you know