0π
β
async FetchData({ state, commit }, to) {
try {
const q = query(collection(db, to));
await onSnapshot(q, (querySnapshot) => {
const allPromises = querySnapshot.docs.map(async (doc) => {
let item = {
id: doc.id,
name: doc.data().name,
slug: doc.data().slug,
country: doc.data().country,
duration: doc.data().duration,
year: doc.data().year,
video: doc.data().video,
genres: doc.data().genres,
actors: doc.data().actors
};
if (to === "films") {
const starsRef = ref(storage, `images/${doc.id}/poster.png`);
item.poster = await getDownloadURL(starsRef);
}
return item;
});
Promise.all(allPromises)
.then((data) => commit("setData", { data, to }))
.catch(console.error);
});
} catch (err) {
console.error(err);
}
}
π€Frallen
4π
You should use Promise.all()
as follows:
const promises = [];
querySnapshot.forEach((doc) => {
const starsRef = ref(storage, `images/${doc.id}/poster.png`);
promises.push(getDownloadURL(starsRef));
});
const urlsArray = await Promise.all(promises);
π€Renaud Tarnec
1π
Map the documents collection to an array of promises that resolve with the full item data, including download URL and await them all with Promise.all().
Youβre also registering a real-time updates listener which seems counter to what you seem to want FetchData
to do. I would suggest you want to use getDocs()
instead of onSnapshot()
async FetchData({ state, commit }, to) {
try {
commit("setLoading", true);
// `onSnapshot` registers a real-time updates listener,
// use `getDocs` to retrieve documents
const { docs } = await getDocs(query(collection(db, to)));
// Map over the `docs` array and return fully hydrated objects
const data = await Promise.all(
docs.map(async (doc) => ({
...doc.data(),
id: doc.id,
poster:
to === "films"
? await getDownloadURL(ref(storage, `images/${doc.id}/poster.png`))
: null,
}))
);
commit("setData", { data, to });
} catch (err) {
console.error(err);
} finally {
commit("setLoading", false);
}
},
If you did want to register a real-time updates listener, do so in an effect hook where you can also remove the listener in a cleanup
useEffect(() => {
// Return the unsub function as cleanup
return onSnapshot(query(collection(db, to)), async ({ docs }) => {
try {
const data = await Promise.all(
docs.map(async (doc) => ({
...doc.data(),
id: doc.id,
poster:
to === "films"
? await getDownloadURL(
ref(storage, `images/${doc.id}/poster.png`)
)
: null,
}))
);
commit("setData", { data, to });
} catch (err) {
console.error(err);
}
});
}, [to]);
π€Phil
Source:stackexchange.com