N
Nuxt4mo ago
whatstaz

Where to fetch initial user data

What is the best practice to load initial user data? Currently I do it in the default.vue layout in an onMounted hook, but that doesn't seem like the right way as sometimes it doesn't work. Here is the code:
const userStore = useUserStore()

const { user } = storeToRefs(userStore)

const accountStore = useAccountsStore()
const categoryStore = useCategoryStore()
const payeeStore = usePayeeStore()
const transactionStore = useTransactionStore()

onMounted(() => {
if (!accountStore.isInitialized) {
accountStore.getAccounts()
accountStore.initialized()
}
if (!categoryStore.isInitialized) {
categoryStore.getCategories()
categoryStore.initialized()
}
if (!transactionStore.isInitialized) {
transactionStore.getTransactions()
transactionStore.initialized()
}
if (!payeeStore.isInitialized) {
payeeStore.getPayees()
payeeStore.initialized()
}
})
const userStore = useUserStore()

const { user } = storeToRefs(userStore)

const accountStore = useAccountsStore()
const categoryStore = useCategoryStore()
const payeeStore = usePayeeStore()
const transactionStore = useTransactionStore()

onMounted(() => {
if (!accountStore.isInitialized) {
accountStore.getAccounts()
accountStore.initialized()
}
if (!categoryStore.isInitialized) {
categoryStore.getCategories()
categoryStore.initialized()
}
if (!transactionStore.isInitialized) {
transactionStore.getTransactions()
transactionStore.initialized()
}
if (!payeeStore.isInitialized) {
payeeStore.getPayees()
payeeStore.initialized()
}
})
Any help would be greatly appreciated!
9 Replies
pyplacca
pyplacca4mo ago
it depends on how you want your app to function. if you want the user data to be fetched before the app loads for instance, you could use a middleware
whatstaz
whatstaz4mo ago
Ah okay, does that still trigger when a user is trying to log in?
pyplacca
pyplacca4mo ago
It depends on how you design it, but it’s achievable
whatstaz
whatstaz4mo ago
Okay thanks for the help!
pyplacca
pyplacca4mo ago
Welcome
Tirius
Tirius4mo ago
Plugin also could be an option
// plugins/init.client.js
import { useGeneralStore } from '~/stores/generalStore';
import { useUserStore } from '~/stores/userStore';

export default defineNuxtPlugin(async () => {
const generalStore = useGeneralStore();
const userStore = useUserStore();

await Promise.all([
generalStore.init(),
userStore.init()
]);
});
// plugins/init.client.js
import { useGeneralStore } from '~/stores/generalStore';
import { useUserStore } from '~/stores/userStore';

export default defineNuxtPlugin(async () => {
const generalStore = useGeneralStore();
const userStore = useUserStore();

await Promise.all([
generalStore.init(),
userStore.init()
]);
});
Hendrik Jan
Hendrik Jan4mo ago
You could try it in "app.vue" (you probably have to create that file, see the docs). Simplified example of my code (I'm using Nuxt useState as you can see):
// app.vue
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>

<script setup lang="ts">
const userData = useState('user');

const data = await useFetch(...);
userData.value = data.value.user;
</script>
// app.vue
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>

<script setup lang="ts">
const userData = useState('user');

const data = await useFetch(...);
userData.value = data.value.user;
</script>
whatstaz
whatstaz4mo ago
That is kinda what I'm doing right now, I found my problem, I was calling my loadUserData in a default.vue layout (which loaded on the login page), after the login, it didn't trigger any more unless I refreshed. I tried the middleware but then it was triggering twice and I could not get rid of the hydration mismatch.
pyplacca
pyplacca4mo ago
here's what I normally use to prevent the double call in the middleware
export default defineNuxtRouteMiddleware(() => {
// Single execution client-only actions
if (process.server || (process.client && !nuxtApp.isHydrating)) return
// any code below this line will be run once on the client side
})
export default defineNuxtRouteMiddleware(() => {
// Single execution client-only actions
if (process.server || (process.client && !nuxtApp.isHydrating)) return
// any code below this line will be run once on the client side
})