Sabbir Sobhani
Sabbir Sobhani

Reputation: 1314

How to get reactive value into setup() method from composable files?

//Composable file getCollection.js
const getCollection = (collection) => {
    const documents = ref(null)
    const error = ref(null)

    let collectionRef = projectFirestore.collection(collection)
        .orderBy('createdAt')

    const unsub = collectionRef.onSnapshot((snap) => {
        let results = []
        console.log('snapshot')
        snap.docs.forEach(doc => {
            doc.data().createdAt && results.push({
                ...doc.data(),
                id: doc.id
            })
        })
        documents.value = results
        error.value = null

    }, (err) => {
        documents.value = null
        error.value = "Could not fetch data"
    })
    watchEffect((onInvalidate) => {
        onInvalidate(() => {
            unsub()
        })
    })

    return {
        error,
        documents,
    }
}

export default getCollection

Vue Component:

<template>
  <div class="chat-window">
    <div v-if="error">{{ error }}</div>
    <div v-if="documents" class="messages" ref="messages">
      <div v-for="doc in formattedDocuments" :key="doc.id" class="single">   //Getting all the values perfectly
        <span class="created-at">{{ doc.createdAt }} ago</span>
        <span class="name">{{ doc.name }}</span>
        <span class="message">{{ doc.message }}</span>
      </div>
    </div>
  </div>
</template>
<script>
import { ref } from "vue";
import getCollection from "../composable/getCollection";
export default {
  setup() {
        const { error, documents} = getCollection("messages");
        
        console.log(error.value) // null 


    return {
      error,
      documents
    }
  }
}
</script>

I am having trouble when I want to access reactive value in setup() method from the composable file getCollection.js . And, it's showing “null” inside setup() method. I can not access values from the setup()

console.log(error.value) // null 
                         // why is error value null here?

But, it’s working perfectly inside template. I am getting all the values of documents and error from template but not from the setup(). How can I get all the values from setup() as well?

Upvotes: 1

Views: 370

Answers (1)

tony19
tony19

Reputation: 138696

You're logging the value of the error ref before it's been updated, which happens asynchronously when the data is loaded successfully.

If you want an update whenever error changes, you could watch it:

import { watch } from "vue";
import getCollection from "../composable/getCollection";

export default {
  setup() {
    const { error, documents } = getCollection("messages");

    watch(error, newErrorValue => {
      console.log(newErrorValue);
    })

    return {
      error,
      documents
    }
  }
}

Upvotes: 2

Related Questions