Search code examples
vuejs3urqlvue3-sfc-loader

Error: use* functions may only be called during the `setup()` or other lifecycle hooks


I have this simple code inside <script lang='ts' setup>:

let isServiceAlive = true;
let articles: IArticle[] = ref(null);

onMounted(async () => 
{
    await loadServiceStatus()

    if (isServiceAlive == false)
        return

    await loadArticles()
})

async function loadServiceStatus()
{
    const { data } = await useQuery(
    { 
        query: GetIsServiceAlive 
    })

    isServiceAlive = data.value.alive
}

async function loadArticles()
{
    const { data } = await useQuery(
    {
        query: GetArticlesQuery
    })

    articles.value = data.value.articles
}

I see nothing inherently wrong in it, but it pops this error:

Uncaught (in promise) Error: use* functions may only be called during the `setup()` or other lifecycle hooks.
    at useClient (useClient.ts?f3e5:28:1)
    at callUseQuery (useQuery.ts?cc4d:72:1)
    at useQuery (useQuery.ts?cc4d:64:1)
    at loadPosts (Index.vue?a170:39:1)
    at eval (Index.vue?a170:24:1)

It disappears as soon as I remove at least one of the calls loadArticles or loadServiceStatus - which is counterproductive.


Solution

  • I found a solution, it's not the default approach you should take with urql - but it's the only approach you want, if you don't want to wrap around reactive objects to access a single property that's returned from the query.

    <script lang='ts' setup>
    import { IArticle } from '@/services'
    import { ref } from 'vue'
    import { GetIsServiceAliveQuery } from './queries/GetIsServiceAliveQuery'
    import { GetArticlesQuery } from './queries/GetArticlesQuery'
    import { useQuery } from '@urql/vue'
    import Article from './Article.vue'
    
    let articles = ref(null)
    let serviceAvailable = ref(false);
    
    useQuery(
    {
        query: GetIsServiceAliveQuery
    })
    .then(result => serviceAvailable.value = result.data.value.alive)
    
    useQuery(
    {
        query: GetArticlesQuery
    })
    .then(result => articles.value = result.data.value.articles)
    </script>