I've been working with Vue and Firebase Firestore.
Currently, I have a dynamic list of individuals being displayed using the v-for
directive. The length of this list is unknown as it is populated asynchronously from Firestore. Handling this part is simple since I can retrieve the data within an onMounted
hook or set up a Firestore listener.
However, for each person in the v-for
, I need to make another asynchronous call to Firestore to fetch their respective images (the image URLs are stored in a separate Firestore document). This particular aspect is posing a challenge for me on how to effectively manage it.
At present, all the images appear broken because the function getPersonImageById(person.id)
performs asynchronously. As a result, it immediately returns undefined
and then later retrieves the image URL. When attempting to load the prop value using await
like so
<img :src="await getPersonImageById(person.id)" />
, I encounter the following error:
Error parsing JavaScript expression: 'await' is only allowed within async functions and at the top levels of modules. (1:1)
Here's a simplified version of my code snippet:
<template>
<div v-for="(person, index) in people" :key="person.id">
{{ person.name }}
<img :src="getPersonImageById(person.id)" />
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
// Simulate async database call (i.e. Firestore)
const databaseAsyncFetch = async (data) => {
await new Promise((resolve) => setTimeout(resolve, 2000));
console.log(data);
return data;
};
// Load the people data
const people = ref();
onMounted(async () => {
people.value = await databaseAsyncFetch([
{ id: '1', name: 'John', fruit: 'Banana' },
{ id: '2', name: 'Mary', fruit: 'Apple' },
{ id: '3', name: 'Luke', fruit: 'Orange' },
]);
});
// Make another async call for each "person" inside the v-for to fetch the images
const getPersonImageById = async (id) => {
await databaseAsyncFetch(
'https://picsum.photos/100/100?random=' + id + '.jpg'
);
};
</script>
You can also access the live example through this link: https://stackblitz.com/edit/vitejs-vite-ljqftl?file=src/App.vue