Open xdiegom opened 6 months ago
Where do you use useAPI
@xdiegom ?
This should be used only for fetching the initial data of the component
Hi @Atinux , thanks for your quick response. I appreciate 🙌🏼.
Specific installed nuxt version: 3.10.1
Basically I use it in components, plugins or middleware like documentation suggests when using useFetch. Because custom useApi
composable uses useFetch()
:
useFetch is a composable meant to be called directly in a setup function, plugin, or route middleware. It returns reactive composables and handles adding responses to the Nuxt payload so they can be passed from server to client without re-fetching the data on client side when the page hydrates.
The warning shows up when using in the client side, for example a Login form action button
I understood that the reason of creating a customFetch
is to reuse it in different parts of the application.
This is my useApi
composable adapted to the current nuxt 3 version I have installed
// composable/useApi.ts
export async function useApi<T>(
path: string,
options: UseFetchOptions<T> = {},
prefix: string = 'api'
) {
const config = useRuntimeConfig();
const apiUrl = config.public.baseURL + '/' + prefix
const jwt = useCookie('AUTH-TOKEN', {
sameSite: 'lax',
secure: true
});
const headerAuthorization: {
Authorization?: string
} = {}
if (jwt.value) {
headerAuthorization.Authorization = `Bearer ${jwt.value}`
}
let headers: any = {
accept: "application/json",
referer: config.public.appUrl,
...(headerAuthorization ?? { headerAuthorization })
}
return useFetch(path, {
baseURL: apiUrl,
watch: false,
...options,
headers: {
...headers,
...options?.headers
},
})
}
Example of use:
// composable/useAuthentication.ts
interface Profile {
id: string,
username: string,
name: string
}
export default function () {
const profile = useState<Profile>(() => ({}));
const login = async (username: string, password: string): Promise<boolean> => {
interface LoginResponse {
token: string
}
const { data, status } = await useApi<LoginResponse>('login', {
body: {
username,
password
},
method: "POST"
})
if (status.value === 'success') {
const token = useCookie('AUTH-TOKEN', {
sameSite: "lax",
secure: true
})
token.value = data.value.token;
return true
}
return false;
}
const getProfile = async (): Promise<void> => {
const { data } = await useApi<Profile>('profile')
profile.value = data.value.data;
}
return { login, getProfile, profile }
}
‼️ Here is where the warning is showing, when clicking the button that triggers the handleSubmit()
function
// BaseLoginForm.vue
<template>
<form @submit.prevent="handleSubmit" class="w-full space-y-3 flex flex-col items-center px-8">
<BaseInput class="w-full" label="username" input-id="username" v-model="username">
</BaseInput>
<BaseInput type="password" class="w-full" label="password" input-id="password" v-model="password">
</BaseInput>
<BaseButton type="submit" class="w-full">
Login
</BaseButton>
</form>
</template>
<script lang="ts" setup>
const { login } = useAuthentication();
const username = ref();
const password = ref();
const handleSubmit = async () => {
await login(username.value, password.value);
}
// middleware/auth.global.ts
export default defineNuxtRouteMiddleware(async (to, from) => {
const { isLoggedIn, getProfile } = useAuthentication();
if (process.server && !isLoggedIn.value) {
await getProfile()
}
})
Thanks again for your reply.
Regards, Diego
Hi @Atinux! Hope you are doing well.
I was wondering if there is an update about creating a custom fetch composable that adapts the current Nuxt version 3.10.X because I believe your blog post is a bit behind from current changes and right know the Nuxt vesion I am using is showing a warning that I haven't solved which is
[nuxt] [useFetch] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching
.I have followed the videos that the community suggest in this nuxt issue but the warning persists.
Thanks!