skip to Main Content

In a Vue 3 app, I need to use a modal component directly on page load. The problem is that this component needs to wait for a specific array to be populated in Vuex, before rendering to the DOM:

  <!--begin::Edit profile tag list -->
  <Modal1
    v-if="$store.state.teammembers.length > 0"
    whichModal="editProfileTags"
    title="Edit tag list"
    buttonText=""
  ></Modal1>
  <!--end::Edit profile tag list-->

In the code above, I am only checking if the array exists and has at least one item. But how can I make sure all existing items have been stored in the array before render?

I don’t know if using props could be a solution, but I would like to avoid it as I find it much easier to work only with centrally stored data (many sibling components).

To get the data in the array in the first place, I am using a Firestore request with a realtime listener:

//Get teammembers
const qTeammembers = query(collection(db, "users"), where("teamid", "==", store.state.userData.teamid));
unsubToTeamMembers = onSnapshot(qTeammembers, (teammembersSnap) => {
    store.state.teammembers = []
    teammembersSnap.docs.forEach((doc9) => {
        let teammember = doc9.data()
        teammember.docid = doc9.id

        //Create an array of team members
        store.state.teammembers.push(teammember)

    })
})

As I am using an onSnapshot I can’t follow up with a .then() method once everything has been fetched.

2

Answers


  1. How about setting a temporary variable (teamMembers) and push each item to that variable instead. Then set it to state afterwards, when all items has been pushed.

    const qTeammembers = query(collection(db, "users"), where("teamid", "==", store.state.userData.teamid));
    unsubToTeamMembers = onSnapshot(qTeammembers, (teammembersSnap) => {
        store.state.teammembers = []
        const teamMembers = []
        teammembersSnap.docs.forEach((doc9) => {
            let teammember = doc9.data()
            teammember.docid = doc9.id
    
            // Create an array of team members
            teamMembers.push(teammember)
        })
        store.state.teammembers = teamMembers
    })
    
    Login or Signup to reply.
  2. I’m not sure, are you using Vue 3 but according to your comment about <suspense> here is an example how you can use asynchronous observer onSnapshot() in a Promise.

    dishList.vue

    <template>
        <ul v-if="data.length">
            <li v-for="item in data" :key="item">{{ item }}</li>
        </ul>
    </template>
    
    <script setup lang="ts">
    import { onSnapshot, collection, getFirestore } from '@firebase/firestore'
    const data = ref([])
    
    await new Promise(resolve => {
        return onSnapshot(collection(getFirestore(), 'dishes'), snap => {
            if (!snap.empty) {
                snap.forEach(docSnap => {
                    data.value.push(docSnap.data())
                })
                setTimeout(() => resolve('done'), 500)
            }
        })
    })
    </script>
    

    app.vue

    <template>
       <Suspense>
          <dishList></dishList>
          <template #fallback>Loding Data...</template>
       </Suspense>
    </template>
    

    If you want more accurate answer to your question you need to provide more code whole components not just little snippet of them.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search