馃摎 What are you trying to do? Please describe.
I feel I should be able to use useQuery from @vue/apollo-composable but I can't see how to do it from the docs.
useQuery requires to be called synchronously within setup() so does useFetch or useAsync.
馃攳 What have you tried?
I've tried to call refetch method from useQuery within useFetch or useAsync but it doesn't work:
const { result, loading, onResult, refetch } = useQuery(/*...*/)
useAsync(() => {
refetch()
})
Since useQuery must be called in setup() function, I was waiting for the nuxt-composition-api module to be able to use @vue/apollo-composable properly but I failed.
I believe that I may encounter this issue using another asynchronous composable library that require to call the useX() within setup().
@KevinNTH
Have you followed the instructions here?
Alternatively, you might be able to create a setup like so:
const { result, loading, onResult, refetch } = useQuery(/*...*/)
const myResult = ssrRef(null)
watch(result, result => (myResult.value = result))
Also, useAsync returns a value so it should be used like so rather than just launching async actions from within it:
const posts = useAsync(() => axios.get('/api/posts'))
Thank you for your answer @danielroe,
So, I was wondering this for the SPA mode, but after thinking about it again, there is no point of using useFetch + useQuery in this mode because we have access to loading and refetch properties.
Therefore, I started to switch my app to universal mode in order to get pre-rendering feature from Nuxt. I've never worked with SSR before so I still have some struggle using Vue Apollo with SSR, but this is not an issue regarding nuxt-composition-api anymore (I'd be happy if you could help me further though).
So I've followed this topic regarding SSR until this part here which I have no idea how I can inject the Apollo SSR state into the Nuxt context for the server-entry.js.
Also, I've tried the snippet you mentionned:
const { result } = useQuery(/*...*/)
const myResult = ssrRef([])
watch(result, result => (myResult.value = result))
It works since I don't get the hydratation issue of mismatching childNodes vs. VNodes but it renders the page with an empty list rather than pre-rendering the actual list. So my last clue is to get the Apollo SSR state working.
Hey,
I've solved my issue. Actually, your snippet works just fine, but I just forget to thing about the loading reference.
Here the final snippet:
const posts = ssrRef([])
const loading = ssrRef(true)
const {
result: queryPosts,
loading: queryLoading,
onResult,
} = useQuery(/*...*/)
onResult(() => {
posts.value = queryPosts.value
loading.value = queryLoading.value
})
Thanks @danielroe for your help! I've learn a lot in the process. I guess the next step would be to inject ApolloSSR.getStates into nuxtState in order to not use ssrRef for each query.
Great! 馃憤
@KevinNTH Do you have a complete example somewhere for using @vue/apollo-composable with nuxt-composition-api ?
More specifically, how do you provide / inject the Apollo Client instance inside Nuxt ?
@lewebsimple It works in exactly the same way in Nuxt as in the vue-apollo docs, with the proviso that rather than adding the provide to App.js, you'll probably add it to your default layout.
See https://v4.apollo.vuejs.org/guide-composable/setup.html#multiple-clients
@lewebsimple Here's my snippet to provide the client into app.setup. I believe this is not a best practice since app.setup may be overridden by another plugin, but I haven't any solution yet for now.
// ~/plugins/provide-apollo-client.js
import { DefaultApolloClient } from '@vue/apollo-composable'
import { provide } from 'nuxt-composition-api'
import { client } from '~/graphql/apollo-client'
export default function apolloClient({ app }, inject) {
app.setup = () => {
provide(DefaultApolloClient, client)
}
}
useSsrResult.ts
import { ssrRef } from '@nuxtjs/composition-api'
import type { UseQueryReturn } from '@vue/apollo-composable'
export default <TResult, TVariables>(
onResult: UseQueryReturn<TResult, TVariables>['onResult']
) => {
const result = ssrRef<TResult | null>(null)
onResult((res) => res?.data && (result.value = res.data))
return result
}
example
const { onResult } = useGetCompilationsQuery({})
const result = useSsrResult(onResult)
Most helpful comment
@lewebsimple It works in exactly the same way in Nuxt as in the
vue-apollodocs, with the proviso that rather than adding the provide toApp.js, you'll probably add it to your default layout.See https://v4.apollo.vuejs.org/guide-composable/setup.html#multiple-clients