Reputation: 2074
I'm trying to use async/await to get images from firebase storage, and this is my function:
import { ref as sRef, getDownloadURL } from "firebase/storage";
...
async getCharacterIconUrl(character) {
return await getDownloadURL(sRef(storage, `characters/${character}/icon`));
}
And then, I use this function here:
import { ref, child, get } from "firebase/database";
...
async componentDidMount() {
const dbRef = ref(db);
let snapshot = await get(child(dbRef, "en/characters"));
if (snapshot.exists()) {
let characters = Object.keys(snapshot.val()).map((key) => {
return {
_id: key,
img: this.getCharacterIconUrl(key),
...snapshot.val()[key],
};
});
this.setState({ characters: characters });
} else {
console.log("No data available");
}
}
The problem I have is that img
inside characters
is never resolved.
How can I solve this?
Upvotes: 0
Views: 719
Reputation: 1054
Since getCharacterIconUrl
is an async function, it returns a promise. Therefore, your img
field is a promise; combined with map()
, that becomes like an array of promise. Therefore, we can use Promise.all()
to resolve them
async componentDidMount() {
const dbRef = ref(db);
let snapshot = await get(child(dbRef, "en/characters"));
if (snapshot.exists()) {
let characterPromises = Object.keys(snapshot.val()).map(async (key) => {
return {
_id: key,
img: await this.getCharacterIconUrl(key),
...snapshot.val()[key],
};
});
this.setState({ characters: await Promise.all(characterPromises)});
} else {
console.log("No data available");
}
}
Upvotes: 1
Reputation: 164729
Your getCharacterIconUrl
function is async
so you need to await it.
Try this...
const characters = await Promise.all(
Object.entries(snapshot.val()).map(async ([_id, val]) => ({
_id,
img: await this.getCharacterIconUrl(_id),
...val,
}))
)
this.setState({ characters });
Note that the .map()
callback is also async
. I'm also using Object.entries()
since you want both keys and values.
Upvotes: 1