Problem vue-query hooks can only be used inside setup() function.
Hi, I am working on a project in which some data of a user is intended to be fetched after a specific button is clicked. I defined an arrow function in composition API and it looks like the following:
I wrap
useQuery
inside the arrow function to pass variables , and the function is to be triggered by button via v-on
. However, clicking the button only leads to the error message: Uncaught Error: vue-query hooks can only be used inside setup() function. So my questions are:
1. Is it prohibited to call useQuery
in functions that are not immediately executed in Vue setup function?
2. Is there other workaround to pass variable into useQuery
?8 Replies
quickest-silver•3y ago
Hi. So you should use your query as const {data, refetch} = fetchUserRelatedPrograms(NUMBER VARIABLE);
To avoid immediately calling query use enabled: boolean parameter, and then on click call refetch()
P.s the best practice is to define your query function as custom hook
stormy-goldOP•3y ago
Could you further explain defining query function as custom hook?
quickest-silver•3y ago
//userQueries.ts
// imports ...
export const useUserRelatedProgramQuery = (uid: number) => useQuery(["reviewerProgram", uid], async () => {
try {
const {data} = await api.getReviewerPrograms(uid);
return data;
} catch (e: any) {
if (e instanceof InvalidSessionError) {
console.error(
"Session has already expired while querying reviewerProgram"
);
router.push("/");
}
}}, {
enabled: someCondition
//another options
});
Then use in vue
// UserComponent.vue
<script setup lang="ts">
import { useUserRelatedProgramQuery } from './userQueries.ts'
const {data, refetch, etc...} = useUserRelatedProgramQuery(userUID)
</script>
<template> <button @click="refetch()"> Fetch user program</button> </template>
stormy-goldOP•3y ago
Thank you. It helps a lot!
quickest-silver•3y ago
You are welcome
stormy-goldOP•3y ago
This solution works on the condition that
userID
is fixed. However, it would still be a problem if I want to pass userID
as a parameter that is changed at runtime. That’s why in my original question I wrap useQuery
in an arrow function.quickest-silver•3y ago
Use
ref or computed
for userID, in queryKey it must be ref as-is (without .value) and in your api call queryFn just unref or .value
ID.
//userQueries.ts
// imports ...
export const useUserRelatedProgramQuery = (
uid: Ref<number>) => useQuery(["reviewerProgram",
uid], async () => {
try {
const {data} = await api.getReviewerPrograms(
uid.value);
return data;
} catch (e: any) {
if (e instanceof InvalidSessionError) {
console.error(
"Session has already expired while querying reviewerProgram"
);
router.push("/");
}
}}, {
enabled: someCondition
//another options
});
Then use in vue
// UserComponent.vue
<script setup lang="ts">
import { useUserRelatedProgramQuery } from './userQueries.ts'
const userUID = ref()
const {data, refetch, etc...} = useUserRelatedProgramQuery(userUID)
</script>
<template> <button @click="refetch()"> Fetch user program</button> </template>
stormy-goldOP•3y ago
Thanks!!!