N
Nuxt3w ago
bnason

useFetch undefined computed

How do I handle dependent values that may be undefined when using useFetch? For instance:
const { data: session } = await useLazyFetch('/api/session')
const { data: me } = await useLazyFetch(`/api/users/${session.value.userId}`)
const { data: session } = await useLazyFetch('/api/session')
const { data: me } = await useLazyFetch(`/api/users/${session.value.userId}`)
Initially it will try to get /api/users/undefined
9 Replies
kapa.ai
kapa.ai3w ago
Hi @bnason. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- When using useFetch (or useLazyFetch) with dependent values that may be undefined (like session.value.userId), you should use a computed getter for the URL that returns undefined or null when the dependency is not ready. This prevents the fetch from being triggered with an invalid URL. Here's how you can handle this:
const { data: session } = await useLazyFetch('/api/session')

const userUrl = computed(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})

const { data: me } = await useLazyFetch(userUrl)
const { data: session } = await useLazyFetch('/api/session')

const userUrl = computed(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})

const { data: me } = await useLazyFetch(userUrl)
With this approach, useLazyFetch will not trigger until userUrl returns a valid string. This pattern is documented in the Nuxt docs for computed URLs and reactive keys, which allow you to construct URLs based on reactive dependencies and avoid fetching with undefined values. When the dependency (session.value.userId) becomes available, the fetch will automatically be triggered with the correct URL Docs: Computed URL Docs: Reactive Keys. Key points: - Use a computed getter for the dependent URL. - Return undefined or null from the computed if the dependency is not ready. - The fetch composable will wait until the computed returns a valid URL before making the request. This prevents requests like /api/users/undefined and ensures your data fetching logic is robust and reactive. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@712351223482810390> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Cake
Cake3w ago
useAsyncData with $fetch
bnason
bnasonOP3w ago
@kapa.ai using a computed gives me a type error because the computed is a string instead of NitroFetchRequest. How about using Cakes idea of useAsyncData with $fetch
kapa.ai
kapa.ai3w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct that using a computed for the URL with useFetch (or useLazyFetch) is the recommended approach for handling dependencies that may be undefined. According to the Nuxt documentation, you can use a computed getter as the URL, and Nuxt will only trigger the fetch when the computed returns a valid string. If the computed returns undefined, the fetch will not be triggered, which prevents requests like /api/users/undefined Docs: Computed URL. Regarding the type error:
The useFetch composable accepts a string, a Request, a Ref<string | Request>, or a function returning a string or Request as the URL. If you are getting a type error, ensure your computed returns either a string or undefined (not just a string), and that you are using the correct signature:
const userUrl = computed(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})

const { data: me } = await useLazyFetch(userUrl)
const userUrl = computed(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})

const { data: me } = await useLazyFetch(userUrl)
This pattern is supported and documented in the official Nuxt docs Reactive Keys and Shared State. Using useAsyncData with $fetch You can also use useAsyncData directly with $fetch for more control, as you suggested. This is especially useful if you want to handle more complex logic or avoid type issues:
const { data: session } = await useAsyncData('session', () => $fetch('/api/session'))
const { data: me } = await useAsyncData(
'me',
() => session.value?.userId ? $fetch(`/api/users/${session.value.userId}`) : null,
{ watch: [session] }
)
const { data: session } = await useAsyncData('session', () => $fetch('/api/session'))
const { data: me } = await useAsyncData(
'me',
() => session.value?.userId ? $fetch(`/api/users/${session.value.userId}`) : null,
{ watch: [session] }
)
Here, the fetch for "me" will only run when session.value.userId is available, and you can use the watch option to re-run the fetch when session changes Docs: useAsyncData. Summary:
- Both useFetch with a computed URL and useAsyncData with $fetch are valid and documented approaches. - Make sure your computed returns string | undefined to avoid type errors. - Use the watch option in useAsyncData for more explicit dependency tracking if needed. If you are still encountering type errors, please provide the exact error message and code snippet for more targeted help. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@712351223482810390> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
bnason
bnasonOP3w ago
@kapa.ai Type ComputedRef<string | undefined> is not assignable to parameter of type:....
kapa.ai
kapa.ai3w ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The knowledge sources confirm that useFetch (and useLazyFetch) accept a computed ref as the URL, and that the computed can return a string or undefined to control when the fetch is triggered. This is shown in the official documentation:
You can use a computed ref or a plain ref as the URL, allowing for dynamic data fetching that automatically updates when the URL changes:
>
const id = computed(() => route.params.id)
const { data: post } = await useFetch(() => `/api/posts/${id.value}`)
const id = computed(() => route.params.id)
const { data: post } = await useFetch(() => `/api/posts/${id.value}`)
Docs: Reactive Keys and Shared State
The accepted types for the URL parameter are:
URL (string | Request | Ref<string | Request> | () => string | Request): The URL or request to fetch. Can be a string, a Request object, a Vue ref, or a function returning a string/Request. Supports reactivity for dynamic endpoints. Docs: useFetch Parameters
If you are getting a type error such as:
Type 'ComputedRef<string | undefined>' is not assignable to parameter of type ...
Type 'ComputedRef<string | undefined>' is not assignable to parameter of type ...
it is likely because you are passing a ComputedRef directly, rather than a function that returns a string or undefined. The correct usage is to pass a function (or arrow function) that returns the computed value, not the computed itself. For example:
const userUrl = computed(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})

// Correct: pass a function that returns the computed value
const { data: me } = await useLazyFetch(() => userUrl.value)
const userUrl = computed(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})

// Correct: pass a function that returns the computed value
const { data: me } = await useLazyFetch(() => userUrl.value)
Alternatively, you can inline the logic:
const { data: me } = await useLazyFetch(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})
const { data: me } = await useLazyFetch(() => {
if (!session.value || !session.value.userId) return undefined
return `/api/users/${session.value.userId}`
})
This approach matches the documented pattern and should resolve the type error, as the composable expects a function returning a string or undefined, not a ComputedRef itself Docs: useFetch Parameters. If you still encounter issues, double-check that you are not passing the computed ref directly, but rather a function that returns its value. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@712351223482810390> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?