Here is what I have tryed to create.
const getPostImgSrc = async (postImg) => {
const imgRef = ref(storage, `postsImgs/${postImg}`);
getDownloadURL(imgRef).then((url) => {
return <img src={url} alt="" />
});
};
However, the problem is that when I searched the web, it seems like the url is unable to render in time since in async it’s still processing which in turn returns me an img with a src=[object promise]. However when I remove the async it dosen’t work since it needs that async otherwised it would be an error.
So I’m wondering if there is a way to get the url from the getDownloadURL() with or without async? Here is what I’m trying to do with the function, for each post someone has created with an image, get that img url and pass it through in which returns an img element with that src.
<div className="post-details">
<p>{post.text}</p>
{post.img === null ? (
<></>
) : (
getPostImgSrc(post.img)
)}
</div>
Thanks in advance 🙂
2
Answers
I think what happens is that you a re mixing two ways of handling Promises, the async/await way and the then/catch way. If you are using then/catch then you don’t need to be inside an async function, on the other side, if you are inside an async function then you should be using the
await
keyword when handling promises and not thethen
method.So instead of:
Let’s use
await
since you already are using an async function:This function now is getting the image url properly, but we have a little issue now, because it is an async function, and all async functions always return a Promise, our
getPostImgSrc
is returningPromise<undefined>
, no matter what you return from an async function it will always be wrapped inside a Promise (in this case the value is undefined beacuse we are not even explicitly returning a value) and as you may know Promises are just objects, so this is why you are getting:Uncaught Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.
Because here:
You are trying to render the value that
getPostImgSrc
returns (which will always be a Promise since this is an async function, which is an object).To fix this we first need to return explicity the image url we are getting in
getPostImgSrc
:Then we need a place to store that value, we will use
useState
for that.Then we need to call
getPostImgSrc
from another place in our component. Because I don’t know how your component code is structured I will call it as soon as the component is rendered, that is usinguseEffect
without dependencies.Finally in the JSX part we put the img tag directly:
The problem with your code is that getDownloadURL is an asynchronous function that returns a Promise. You need to use async/await or .then() to handle the result of the Promise.
Then in your post-details component, you can call the getPostImgSrc function to render the image.