'How to update a Vue ref using a Watch inside a composable?
I have a Vue composable named getDocument that gets a Firebase document.
The code inside onSnapshot callback runs asynchronously. And I'm trying to update the document and error refs with values returned from onSnapshot.
But I want to avoid using a Watch outside the getDocument if possible, because always having to wrap my code in a Watch is a pain.
Instead I want to put a Watch inside the getDocument.ts and have it update the document and error refs there.
This is what I have so far, with no Watch inside getDocument.ts.
src/composable/getDocument.ts
import { ref, watchEffect, watch } from 'vue';
import { db } from 'src/firebase/config';
import {
doc,
onSnapshot,
DocumentSnapshot,
DocumentData,
} from 'firebase/firestore';
const getDocument = (collectionString: string, documentId: string) => {
const error = ref<string | undefined>();
const document = ref<DocumentData | undefined>();
const docRef = doc(db, collectionString, documentId);
const unsubscribe = onSnapshot(
docRef,
(doc: DocumentSnapshot<DocumentData>) => {
if (doc.data()) {
document.value = {
...doc.data(),
id: doc.id,
};
error.value = undefined;
} else {
error.value = "That document doesn't exist";
}
},
(err) => {
console.log(err.message);
error.value = 'Could not fetch documents';
}
);
// Cancel the listener when composable not in use
watchEffect((onInvalidate) => {
onInvalidate(() => {
unsubscribe();
});
});
// Maybe use a "Watch" here to update the doucment and error refs? But I can't get it working.
return { document, error };
};
export default getDocument;
Now when importing the getDocument composable I could wrap everything in a Watch to make sure the ref has a value. But I would rather do that inside getDocument instead.
For example:
src/composable/anotherComposable.ts
import getDocument from 'src/composables/getDocument';
const { document, error } = getDocument('users', 'USER_ID_HERE');
// I could wrap all my code here in a Watch, but I was hoping to avoid that. I want to use the Watch inside the getDocument composable to do the same thing.
watch(document, () => {
console.log(document.value);
});
// This is how I would like to ultimately use the document ref after the Watch is moved inside the getDocument composable. Currently this will show as undefined. So I need to somehow put a Watch inside the getDocument composable to make this have a value.
console.log(document.value);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
