From 6fcc9798774bd5b76ecf90335b7a7d9817dbfdc9 Mon Sep 17 00:00:00 2001 From: Italo Date: Wed, 27 Sep 2023 11:33:08 -0300 Subject: [PATCH] docs: improve data fetching section (#23420) --- docs/1.getting-started/6.data-fetching.md | 142 ++++++++++++++++------ 1 file changed, 107 insertions(+), 35 deletions(-) diff --git a/docs/1.getting-started/6.data-fetching.md b/docs/1.getting-started/6.data-fetching.md index 27995d5107..eadd169e8b 100644 --- a/docs/1.getting-started/6.data-fetching.md +++ b/docs/1.getting-started/6.data-fetching.md @@ -5,25 +5,25 @@ description: Nuxt provides composables to handle data fetching within your appli # Data fetching -Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/api/composables/use-async-data) and `$fetch` . +Nuxt comes with two composables and a built-in library to perform data-fetching in browser or server environments: `useFetch`, [`useAsyncData`](/docs/api/composables/use-async-data) and `$fetch` . In a nutshell: -Used together, they ensure cross-environment compatibility and efficient caching and avoid duplicate network calls. +- [`useFetch`](/docs/api/composables/use-fetch) is the most straightforward way to handle data fetching in a component setup function. +- [`$fetch`](/docs/api/utils/dollarfetch) is great to make network requests based on user interaction. +- [`useAsyncData`](/docs/api/composables/use-async-data), combined with `$fetch`, offers more fine-grained control. -[`useFetch`](/docs/api/composables/use-fetch) is the most straightforward way to handle data fetching in a component setup function. +Both `useFetch` and `useAsyncData` share a common set of options and patterns that we will detail in the last sections. -On the other hand, when wanting to make a network request based on user interaction, `$fetch` is almost always the right handler to go for. - -If you need more fine-grained control, you can use [`useAsyncData`](/docs/api/composables/use-async-data) and `$fetch` independently. - -The two composables share a common set of options and patterns that we will detail in the last sections. +Before that, it's imperative to know why these composables exist in the first place. ## Why using specific composables? -When using a framework like Nuxt that can perform calls and render pages on both client and server environments, some challenges must be addressed. This is why Nuxt provides composables to wrap your queries. +When using a framework like Nuxt that can perform calls and render pages on both client and server environments, some challenges must be addressed. This is why Nuxt provides composables to wrap your queries, instead of letting the developer rely on `$fetch` calls alone. ### Network calls duplication -The [`useFetch`](/docs/api/composables/use-fetch) and [`useAsyncData`](/docs/api/composables/use-async-data) composables ensure that once an API call is made on the server, the data is properly forwarded to the client in the payload. This JavaScript object is accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload) and is used on the client to avoid refetching the same data when the code is executed in the browser. +The [`useFetch`](/docs/api/composables/use-fetch) and [`useAsyncData`](/docs/api/composables/use-async-data) composables ensure that once an API call is made on the server, the data is properly forwarded to the client in the payload. + +The payload is a JavaScript object accessible through [`useNuxtApp().payload`](/docs/api/composables/use-nuxt-app#payload). It is used on the client to avoid refetching the same data when the code is executed in the browser. ::alert{icon=⚙️} Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the payload tab. @@ -31,7 +31,7 @@ Use the [Nuxt DevTools](https://devtools.nuxt.com) to inspect this data in the p ### Suspense -Nuxt uses Vue’s `` component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-calls basis. +Nuxt uses Vue’s [``](https://vuejs.org/guide/built-ins/suspense) component under the hood to prevent navigation before every async data is available to the view. The data fetching composables can help you leverage this feature and use what suits best on a per-calls basis. ::alert{icon=👉} These composables are auto-imported and can be used in `setup` functions or lifecycle hooks @@ -39,7 +39,7 @@ These composables are auto-imported and can be used in `setup` functions or life ## `useFetch` -[`useFetch`](/docs/api/composables/use-fetch) is the most straightforward way to perform data fetching. It is a wrapper around the [`useAsyncData`](/docs/api/composables/use-async-data) composable and `$fetch` utility. +The [`useFetch`](/docs/api/composables/use-fetch) composable is the most straightforward way to perform data fetching. ```vue [app.vue] + + +``` + +For finer control, the `status` variable can be: + +- `idle` when the fetch hasn't started +- `pending` when a fetch has started but not yet completed +- `error` when the fetch fails +- `success` when the fetch is completed successfully + ## Passing Headers and cookies When we call `$fetch` in the browser, user headers like `cookie` will be directly sent to the API. But during server-side-rendering, since the `$fetch` request takes place 'internally' within the server, it doesn't include the user's browser cookies, nor does it pass on cookies from the fetch response. @@ -245,6 +310,7 @@ The example below adds the request headers to an isomorphic `$fetch` call to ens ```vue ``` @@ -266,11 +332,15 @@ Be very careful before proxying headers to an external API and just include head import { appendResponseHeader, H3Event } from 'h3' export const fetchWithCookie = async (event: H3Event, url: string) => { + /* Get the response from the server endpoint */ const res = await $fetch.raw(url) + /* Get the cookies from the response */ const cookies = (res.headers.get('set-cookie') || '').split(',') + /* Attach each cookie to our incoming Request */ for (const cookie of cookies) { appendResponseHeader(event, 'set-cookie', cookie) } + /* Return the data of the response */ return res._data } ``` @@ -279,7 +349,9 @@ export const fetchWithCookie = async (event: H3Event, url: string) => { ```