I am currently working on a Vue 3 composable that fetches navigation menus asynchronously. However, I am facing an issue where the exported values are not available when importing them in a component. I would like to find a way to be notified once these values are ready.
(I am using this composable with Nuxt 3, so you may not see imports in my code since they are auto-imported).
// composables/useNavigation.js
// creating a global variable for shared state
const navs = reactive({
main: false,
footer: false,
})
export const useNavigation = async () => {
const runTimeConfig = useRuntimeConfig()
const endpointMenus = `${runTimeConfig.public.API_URL}/wp-api-menus/v2/menus`
const { data: menus, pending, error } = await useFetch(endpointMenus)
Object.keys(navs).forEach(async (key) => {
const menuID = menus.value.find((m) => m.slug === key)?.ID
const endpointMenu = `${runTimeConfig.public.API_URL}/wp-api-menus/v2/menus/${menuID}`
const { data: menu } = await useFetch(endpointMenu)
navs[key] = menu.value
console.log('navs.value: ', toRaw(navs))
})
return {
...toRefs(navs),
test: toRef(navs.main),
}
}
In my component file:
// /pages/[slug].vue
<script setup>
const { main, test } = useNavigation()
console.log('main1: ', main)
console.log('test1: ', test)
watch(
main,
(newValue, oldValue) => {
console.log('newValue: ', newValue)
},
{ deep: true, immediate: true },
)
const menu = computed(() => {
console.log('main: ', main)
return main
})
setTimeout(() => {
console.log('main2: ', main)
console.log('test2: ', test)
}, 3000)
The initial console log displays both main and test as undefined
.
During the timeout period, I can observe that the navs object is correctly filled with the results.
After 3 seconds, main and footer should be updated, but upon logging them again, they remain undefined.
Additionally, the watcher does not seem to trigger.
What could I be overlooking? I tried including the toRefs
part to maintain reactivity, but it did not resolve the issue.