N
Nuxt6mo ago
jd

Best practices for state/composable to depend on fetched data?

I have a useUser composable that fetches API data to build the user: userInfo and companyInfo. I get the error that a composable is used outside the Nuxt instance. I want to know the best practices for implementing something like this, if anyone knows enough to help Here's the code for the user composable and the user plugin. composables/useUser.js 
export const useUser = async () => {
async function refresh() {
const authUser = useSupabaseUser()

const { data: userInfo, error: userError } = await useFetch(
`/user/${authUser.value.id}`,
)

const { data: company, error: companyError } = await useFetch(
`/company/${userInfo.value.company_id}`,
)

return { ...userInfo.value, company: company.value }
}

const fetchedUser = await refresh()
const user = useState('user', () => fetchedUser)

return { user, refresh }
}
export const useUser = async () => {
async function refresh() {
const authUser = useSupabaseUser()

const { data: userInfo, error: userError } = await useFetch(
`/user/${authUser.value.id}`,
)

const { data: company, error: companyError } = await useFetch(
`/company/${userInfo.value.company_id}`,
)

return { ...userInfo.value, company: company.value }
}

const fetchedUser = await refresh()
const user = useState('user', () => fetchedUser)

return { user, refresh }
}
plugins/user-plugin.js
export default defineNuxtPlugin((nuxtApp) => {
const { user, refresh } = useUser()
console.log('user-plugin', user)
})
export default defineNuxtPlugin((nuxtApp) => {
const { user, refresh } = useUser()
console.log('user-plugin', user)
})
4 Replies
Mähh
Mähh6mo ago
Do not await on top level in your composables.
export const useUser = useAsyncData('some-unique-key', async () => {
const user = await $fetch(`/user/${id}`)
const company = await $fetch(`/company/${user.companyId}`)

return { ...user, company }
})
export const useUser = useAsyncData('some-unique-key', async () => {
const user = await $fetch(`/user/${id}`)
const company = await $fetch(`/company/${user.companyId}`)

return { ...user, company }
})
export default defineNuxtPlugin(async (nuxtApp) => {
const {data: user, refresh} = await useUser()
})
export default defineNuxtPlugin(async (nuxtApp) => {
const {data: user, refresh} = await useUser()
})
https://nuxt.com/docs/api/composables/use-async-data https://nuxt.com/docs/guide/going-further/nuxt-app#the-nuxt-context https://nuxt.com/docs/getting-started/data-fetching
jd
jdOP6mo ago
Hey @Mähh thanks a lot! I love the simplicity of the suggestion! I still have the same error I had before.
[500] [nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug.
[500] [nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function. This is probably not a Nuxt bug.
Seems linked to the use of useAsyncData in the composable (from the stack)
Mähh
Mähh6mo ago
from docs, nuxtPlugin should be in the nuxt context. useAsync is only available in such contexts. any reason why you do it in a plugin, and not e.g. in a middleware? Anyways, you can give nuxtApp.runWithContext a try https://nuxt.com/docs/api/composables/use-nuxt-app#runwithcontext
Nuxt
useNuxtApp · Nuxt Composables
Access the shared runtime context of the Nuxt Application.
jd
jdOP6mo ago
I still have the problem that running useAsyncData in a composable returns a 500 And I can't, for the life of me, understand how to use runWithContext
Want results from more Discord servers?
Add your server