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);
}
}
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);
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]);
Source:stackexchange.com