T
TanStack2y ago
rising-crimson

Am I doing composables wrong?

I have a component that ended up with a lot of queries that were used to derive a value, so I figured I'd refactor that logic into its own file, but I'm having some trouble getting vue-query to work in a composable scenario. Here's a redacted and simplified version of what my external module now looks like:
export function useDownloadStatus (filename: string) {
const status = ref('loading')

watchEffect(() => {
const [
{ data: headData, isPending: headPending },
{ data: getData, isPending: getPending },
] = [
headQuery(filename), // these are directly mapped to useQuery() with some predefined settings for query key and queryFn
getQuery(filename),
]
status.value = (() => {
if (headPending) return 'loading'
if (headData.value) return 'downloadable'

if (getPending) return 'loading'
if (!getData.value) return 'nonexistent'

// [..more logic for other statuses]

return 'fallbackvalue'
})()
})
return status
}
export function useDownloadStatus (filename: string) {
const status = ref('loading')

watchEffect(() => {
const [
{ data: headData, isPending: headPending },
{ data: getData, isPending: getPending },
] = [
headQuery(filename), // these are directly mapped to useQuery() with some predefined settings for query key and queryFn
getQuery(filename),
]
status.value = (() => {
if (headPending) return 'loading'
if (headData.value) return 'downloadable'

if (getPending) return 'loading'
if (!getData.value) return 'nonexistent'

// [..more logic for other statuses]

return 'fallbackvalue'
})()
})
return status
}
My component button.vue uses the composable like any other, by importing it and const status = useDownloadStatus("foo") from <script setup> While I can see the network requests being made, it seems like the queries reactivity disappear along the way, leaving the status left on loading and a ill-boding warning from vue-query in the console:
vue-query composables like "useQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.
vue-query composables like "useQuery()" should only be used inside a "setup()" function or a running effect scope. They might otherwise lead to memory leaks.
Any ideas what I'm missing?
1 Reply
rising-crimson
rising-crimsonOP2y ago
Ugh. I moved the headQuery() and getQuery() calls and destructuring to outside watchEffect() and now the error is gone. I cant believe I've spent 4 hours trying all kinds of things and it didn't occur to me until now 🤦‍♂️ I still have trouble with the reactivity but I suspect thats more due to me not understanding watchEffect() and less to do with vue-query Ah, it was because I was using isPending in my conditions rather than isPending.value. It's all very... humbling.

Did you find this page helpful?