Here I am trying to get productList from MySQL database and for each product object I am assigning new property - imageURL via getImages(). When I log productList to console, there is property imageURL with correct url. Problem is, when I try to map it, it shows nothing. Why?
const storageRef = firebase.storage().ref("/assets")
const [productList, setProductList] = useState([])
useEffect(() => {
Axios.get("http://localhost:3001/product/get").then((response) => {
setProductList(response.data)
})
}, [])
useEffect(() => {
getImages(productList)
}, [productList])
const getImages = (array) => {
array.forEach((item) => {
storageRef.child(`${item.bannerImage}`).getDownloadURL().then((url) => {
item.imageURL = url
})
})
}
My map function:
{productList.map((val) => {
return (
<div key={val.id} className="product">
<div className="item">
<h1>Product title: {val.title}</h1>
<h2>Price: {val.price}</h2>
<h2>Quantity: {val.quantity}</h2>
<h2>IMAGE: {val.imageURL}</h2>
</div>
</div>
)
})}
Problems:
- You are not setting
productList
back ingetImages
function. You are just iterating over array.getDownloadURL
is aasync
function, you should not use it inside loop. The best way to do this is through arecursive
function. But you can also do this as below:
Your getImage
function
const getImage = async (bannerImage) => {
const url = await storageRef.child(bannerImage).getDownloadURL();
return url;
}
then your map
function
{productList.map((val) => {
return (
<div key={val.id} className="product">
<div className="item">
<h1>Product title: {val.title}</h1>
<h2>Price: {val.price}</h2>
<h2>Quantity: {val.quantity}</h2>
<h2>IMAGE: {getImage(val.bannerImage)}</h2>
</div>
</div>
)
})}