Replies: 12 comments 26 replies
-
You |
Beta Was this translation helpful? Give feedback.
-
If you want to use // composables/mHttp.ts
export const useFetchPost = (url: string, param?: object, key?: string) =>
useFetch(url, {
watch: false,
method: 'POST',
body: param,
immediate: false,
key,
}) <script setup lang="ts">
const { refresh, data } = useFetchPost('/api/test', {})
const click = () => {
refresh().then(() => {
navigateTo('/conter')
})
}
</script> export default defineNuxtConfig({
optimization: {
keyedComposables: [
{
name: 'useFetchPost',
argumentLength: 3
}
]
}
}) |
Beta Was this translation helpful? Give feedback.
-
I get this warning with // file: ~/middleware/auth.global.ts
export default defineNuxtRouteMiddleware(async () => {
const { user } = useAuth()
const { data } = await useFetch('/api/auth/user')
user.value = data.value
}) The documentation states:
If I use export default defineNuxtRouteMiddleware(async () => {
const { user } = useAuth()
user.value = await $fetch('/api/auth/user')
}) According to the docs:
Using the first method, everything works presto, apart from the warning. So this is a tad bit confusing. Can you elaborate @manniL? |
Beta Was this translation helpful? Give feedback.
-
I share the same confusion. My project requires SSR, so I migrated from Vue 3 to Nuxt 3. The problem this brought was that I needed to convert all axios requests to the useFetch approach. This is not a small task, but I am working hard on it. During development, I repeatedly read the documentation and could roughly understand the design concepts of useFetch, useAsyncData, and $fetch. SSR requires hydration, so in most cases, using useFetch can effectively solve problems related to data requests. I once thought this was the recommended approach in Nuxt 3. But I only recently upgraded to Nuxt 3.10.x, and I also encountered this prompt. The hint seems to suggest, "Hey, you shouldn't use useFetch for everything, you need to use $fetch to implement best practices and compensate for the shortcomings of useFetch." However, the provided documentation is not specifically aimed at resolving this prompt. Moreover, I cannot achieve my goal by simply replacing useFetch with $fetch, and the documentation does not mention how to implement it. This also left me confused for a while. It would be very helpful if the Nuxt official could provide a clear document to tell us how to specifically solve this problem. |
Beta Was this translation helpful? Give feedback.
-
I use useFetch in my pinia stores... and I get this warning. |
Beta Was this translation helpful? Give feedback.
-
Nuxt 3.10.3 and
I'm using await useAsyncQuery(query, input) in a function called in my setup (composition API) and still see this error. The query in in this case is a graphql query using nuxtjs/apollo per above. The calls complete before onMounted for the page is called. |
Beta Was this translation helpful? Give feedback.
-
i want to do pagination with usefetch, but I got following problem <template>
<component :value="data"/>
</template>
<script setup>
const route = useRoute()
const page = ref(route.query.page)
const {data} = await useFetch(`myapi/${page.value})
watch(() => route.query, () => {
page.value = route.query.page
// the page ref was updated, but the data get by useFetch will not get fetched
// if i use useFetch again i got warnning
)
//...
</script> |
Beta Was this translation helpful? Give feedback.
-
这是一封自动回复邮件。已经收到您的来信,我会尽快回复。
|
Beta Was this translation helpful? Give feedback.
-
I found the solution and it's working for me, nuxtApp.runWithContext(async () => {}); composables/useHttp.ts import type { Pinia } from "pinia";
export function useHttp() {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const nuxtApp = useNuxtApp();
const mainStore = useMainStore(nuxtApp.$pinia as Pinia);
const { setPwaToken } = useSettings();
const getHeaders = computed((): HeadersInit => {
const requestHeaders = useRequestHeaders(["cookie"]) as HeadersInit;
if (mainStore.pwaToken && mainStore.pwaCode) {
requestHeaders["Pwa-Token"] = mainStore.pwaToken;
requestHeaders["Pwa-Code"] = mainStore.pwaCode;
}
if (process.client) {
if (document.cookie) {
const currentCookies = document.cookie.split(";") as any;
requestHeaders["pwacookie"] = currentCookies;
}
}
return requestHeaders;
});
type SendRequestResponse = {
data: any;
pending: any;
error: any;
//refresh: any;
};
const sendPostRequest = async (
url: string,
sendData: any,
lazy = false,
signal?: AbortSignal
): Promise<SendRequestResponse> => {
return nuxtApp.runWithContext(async (): Promise<SendRequestResponse> => {
const { data, pending, error } = await useFetch(url, {
method: "POST",
body: sendData,
headers: getHeaders.value as HeadersInit,
credentials: "include",
signal,
lazy,
});
if (error.value) {
if (error.value.statusCode == 503) {
await new Promise((resolve) => setTimeout(resolve, 200)); // wait before retrying
return sendPostRequest(url, sendData, lazy, signal);
}
}
if (data.value) {
if (Object.prototype.hasOwnProperty.call(data.value, "pwaCookie")) {
const pwaCookie = data.value["pwaCookie"];
delete data.value["pwaCookie"];
pwaCookie.forEach((cookie: any) => {
const cookieArr = cookie.split(";");
const name = cookieArr[0].split("=")[0];
const value = cookieArr[0].split("=")[1];
const exDate = cookieArr[1].split("=")[1];
const generatedCookie =
name + "=" + value + ";expires=" + exDate + ";path=/";
if (process.client) {
document.cookie = generatedCookie;
}
});
}
if (Object.prototype.hasOwnProperty.call(data.value, "token-valid")) {
if (data.value["token-valid"] === false) {
await setPwaToken();
await new Promise((resolve) => setTimeout(resolve, 200)); // wait before retrying
return sendGetRequest(url, lazy, signal);
}
}
}
return new Promise((resolve, reject) => {
if (error.value) {
reject({ data, pending, error });
} else {
resolve({ data, pending, error });
}
});
});
};
const sendGetRequest = async (
url: string,
lazy = false,
signal?: AbortSignal
): Promise<SendRequestResponse> => {
return nuxtApp.runWithContext(async (): Promise<SendRequestResponse> => {
const { data, pending, error } = await useFetch(url, {
method: "GET",
headers: getHeaders.value as HeadersInit,
credentials: "include",
signal,
lazy,
});
if (error.value) {
if (error.value.statusCode == 503) {
await new Promise((resolve) => setTimeout(resolve, 200)); // wait before retrying
return sendGetRequest(url, lazy, signal);
}
}
if (data.value) {
if (Object.prototype.hasOwnProperty.call(data.value, "pwaCookie")) {
const pwaCookie = data.value["pwaCookie"];
delete data.value["pwaCookie"];
pwaCookie.forEach((cookie: any) => {
const cookieArr = cookie.split(";");
const name = cookieArr[0].split("=")[0];
const value = cookieArr[0].split("=")[1];
const exDate = cookieArr[1].split("=")[1];
const generatedCookie =
name + "=" + value + ";expires=" + exDate + ";path=/";
if (process.client) {
document.cookie = generatedCookie;
}
});
}
if (Object.prototype.hasOwnProperty.call(data.value, "token-valid")) {
if (data.value["token-valid"] === false) {
await setPwaToken();
await new Promise((resolve) => setTimeout(resolve, 200)); // wait before retrying
return sendGetRequest(url, lazy, signal);
}
}
}
return new Promise((resolve, reject) => {
console.log("Response received from server", {
data: data.value,
pending: pending.value,
error: error.value,
});
if (error.value) {
reject({ data, pending, error });
} else {
resolve({ data, pending, error });
}
});
});
};
return {
getHeaders,
sendPostRequest,
sendGetRequest,
};
} Then use it anywhere: const { sendPostRequest, sendGetRequest } = useHttp();
sendPostRequest(getEndpointUrl("getConfigs"), {
paths: configPaths.join(","),
})
.then((res: any) => {
const data = res.data.value;
}).catch((e) => {
console.log(e);
}); |
Beta Was this translation helpful? Give feedback.
-
Here is another solution that worked perfectly for me, I've just finished and tested it: I've created a plugin as follows: import { useAPIEndpoints } from "~/composables/useAPIEndpoints";
export default defineNuxtPlugin({
name: "eptAPI",
setup() {
const { API_URL } = useAPIConfig();
const { API_ENDPOINTS } = useAPIEndpoints();
const pwaToken = useCookie("eptPwaToken");
const pwaCode = useCookie("eptPwaCode");
const pwaCookie = useCookie("eptPwaCookie");
const createToken = async () => {
const { data, status } = await useFetch<{ access: string }>(
API_URL + API_ENDPOINTS.getToken,
{
method: "GET",
}
);
if (status.value === "success") {
const response = data.value;
pwaToken.value = response["Pwa-Token"];
pwaCode.value = response["Pwa-Code"];
return {
pwaToken: response["Pwa-Token"],
pwaCode: response["Pwa-Code"],
};
} else {
throw new Error("Generate token failed");
}
};
const eptAPI = async (
url: string,
data?: any,
immediate = true,
signal?: AbortSignal,
lazy = false
) => {
return useFetch(url, {
baseURL: API_URL,
method: data ? "POST" : "GET",
body: data,
immediate,
signal,
lazy,
onRequest: async ({ options }) => {
options.headers = options.headers || {};
options.headers["Content-Type"] = "application/json";
if (pwaCookie.value) {
options.headers["pwacookie"] = pwaCookie.value;
}
if (!pwaToken.value || !pwaCode.value) {
await createToken();
}
options.headers["Pwa-Token"] = pwaToken.value;
options.headers["Pwa-Code"] = pwaCode.value;
},
onResponse: async ({ response }) => {
if (response.status === 503) {
return await eptAPI(url, data);
}
if (response._data["token-valid"] == false) {
await createToken();
return await eptAPI(url, data);
}
},
});
};
return {
provide: {
eptAPI,
},
};
},
});
You can of course get rid of "createToken". Then you can use it in components as follows: const { $eptAPI } = useNuxtApp(); // get the plugin instance
const menuItems = ref([]);
const { data: menuData } = await $eptAPI(API_ENDPOINTS.getMenu, {
menu_code: "main_menu_en",
}); Also can be used in a function: const { $eptAPI } = useNuxtApp(); // get the plugin instance
const { data, execute } = await $eptAPI(
API_ENDPOINTS.getMenu,
{
menu_code: 'main_menu_en',
},
false // immediate = false
);
// Declare the execution
const getMenu = async () => {
console.log("call menu sendPostRequest");
await execute();
if (data.value?.success) {
menuItems.value = data.value.menu_items;
}
};
// then call it to render in the client side as follows:
getMenu();
// or call it in useAsyncData to render in server-side:
await useAsyncData("initMenu", () => getMenu()); |
Beta Was this translation helpful? Give feedback.
-
It has become so difficult to use |
Beta Was this translation helpful? Give feedback.
-
export const useFetchSelf = (
const { sysset } = await useFetchPost('/api/test') const login = () => { const login2 = () => { <el-button type="primary" size="default" @click="form.login">Login |
Beta Was this translation helpful? Give feedback.
-
pages/a.vue
`<script setup lang="ts">
const click = async () => {
</script> Test `useFetchPost("/api/test", {})
.then(async res => {
await navigateTo('/conter')
})
}
composables/mHttp.ts
export const useFetchPost = <T>( url: string, param?: object ) => new Promise<T>((resolve, reject) => { return useFetch(url, { watch: false, method: 'POST', body: param }) .then(resolve) .catch(reject) }
Console Warning
[nuxt] [useFetch] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching
This warning appears on the console every time a button is clicked to send a request. It appears after updating to version 3.10. What is the reason for this
Beta Was this translation helpful? Give feedback.
All reactions