Reputation: 1390
I have an ECommerce project, and this project contains the operations of displaying products, creating a product, deleting a product, and displaying a specific product information.
And my problem is only in displaying the data.
Where through the App file, the data is fetched from the backend and passed to the component "Products" and then displayed on the interface.
The problem is that the data was fetched from the backend and the data coming from the backend appeared in the browser and the request succeeded, but the problem is that the data was not displayed on the interface, and the interface was completely empty.
How can I solve this problem?
App.js:
import * as React from "react";
import Navbar from "./Navbar";
import Products from "./Products";
import { getAllProducts } from "../services/ECommerceServices";
const App = () => {
console.log("Hi in App file");
// const [products, setProducts] = React.useState([]);
const getAllProductsFun = () => {
console.log("Hi I am in App file get all products");
getAllProducts().then((products) => {
// console.log(products);
// setProducts(products);
console.log("pppppppppppp: ", products);
return products;
});
};
return (
<>
<Navbar />
<Products getAllProductsFun={getAllProductsFun} />
</>
);
};
export default App;
products.js:
import * as React from "react";
import { styled } from "@mui/material/styles";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Grid from "@mui/material/Grid";
import { makeStyles } from "@mui/styles";
import { Typography } from "@mui/material";
import Head from "next/head";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";
import Dialog from "./Dialog";
import Product from "./Product";
import { getAllProducts } from "../services/ECommerceServices";
const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === "dark" ? "#1A2027" : "#fff",
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: "center",
color: theme.palette.text.secondary,
}));
const useStyles = makeStyles({
main: {
padding: "4rem ",
},
typo: {
color: "#ffc400 !impoertant",
},
// button: {
// textTransform: "none !important",
// backgroundColor: "#ffc400 !important",
// color: "white !important",
// padding: 14,
// },
});
function Products({ getAllProductsFun }) {
console.log("check: ", getAllProductsFun);
const theme = useTheme();
const breakpoint = useMediaQuery(theme.breakpoints.down("sm"));
return (
<>
<Head>
<title>Solek</title>
</Head>
<Grid
container
direction={breakpoint ? "column" : "row"}
style={{ margin: "4rem" }}
>
<Grid item xs={12} sm={9} md={9}>
<Typography
variant="h4"
gutterBottom
component="div"
// className={classes.typo}
style={{ fontWeight: 600 }}
>
Our Products
</Typography>
</Grid>
<Grid
item
xs={12}
md={3}
sm={3}
style={{
direction: "row",
justifyContent: "flex-end",
alignItems: "center",
}}
>
<Dialog />
</Grid>
</Grid>
<Box sx={{ flexGrow: 1, margin: 8 }}>
<Grid container spacing={3}>
{getAllProductsFun()?.map((product, index) => (
<Grid item xs={12} sm={6} md={3} key={index}>
<Item>
{" "}
<Product key={product.id} product={product} />;
</Item>
</Grid>
))}
</Grid>
</Box>
</>
);
}
export default Products;
EcommerceServices.js:
import axios from "axios";
// [id]
// get All Products
// export async function getAllProducts() {
// const res = await axios.get("https://fakestoreapi.com/products");
// const products = await res.data;
// console.log("products: ", products);
// return products;
// }
export async function getAllProducts() {
const res = await axios
.get("https://fakestoreapi.com/products")
.then((res) => {
const products = res.data;
console.log("products: ", products);
return products;
});
return res;
}
// get element by ID
export async function getSingleProductRequest(context) {
const id = context.params.id;
const req = await axios.get("https://fakestoreapi.com/products/" + id);
const product = await req.json();
console.log("product: ", product);
return product;
}
// get product by ID
export async function getProductsOneByOne() {
const req = await fetch("https://fakestoreapi.com/products");
const products = await req.json();
const paths = products.map((product) => {
return {
params: {
id: product.id.toString(),
},
};
});
return {
paths,
fallback: false,
};
}
// delete product
export const deleteProduct = async (id) => {
await axios
.delete(`https://fakestoreapi.com/products/${id}`)
.then((res) => {
res.json();
console.log("data: ", res.json());
})
.then((json) => {
console.log("json data: ", json);
})
.catch((err) => console.log("error: ", err));
};
Upvotes: 0
Views: 1349
Reputation: 10648
The problem is that your getAllProductsFun
api call is asynchronous. So you'll need to save those values and then display it rather than attempting to call it on render.
In your App.js you can create a state to store the fetched products and call the function on your app mounting like this:
const App = () => {
const [products, setProducts] = React.useState([]) // defaults to empty array
...
React.useEffect(() => {
getAllProducts().then(response => setProducts(response))
}, []) // empty deps array means it will only call once on mount
return (
<>
<Navbar />
<Products products={products} />
</>
);
}
Now you can render the results in Products
like this:
function Products({ products }) {
...
return (
...
{products.map(...)}
...
)
}
Upvotes: 1