docs: add serialization section to data fetching (#19336)

This commit is contained in:
Mahdi Boomeri 2023-03-20 14:08:42 +03:30 committed by GitHub
parent 67c786471f
commit 7be41b9a6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 104 additions and 7 deletions

View File

@ -135,26 +135,26 @@ You can make use of the `refresh()` method returned from the `useFetch()` compos
```vue
<script setup>
const page = ref(1);
const page = ref(1)
const { data: users, pending, refresh, error } = await useFetch(() => `users?page=${page.value}&take=6`, { baseURL: config.API_BASE_URL }
);
)
function previous() {
page.value--;
refresh();
page.value--
refresh()
}
function next() {
page.value++;
refresh();
page.value++
refresh()
}
</script>
```
The key to making this work is to call the `refresh()` method returned from the `useFetch()` composable when a query parameter has changed.
By default, `refresh()` will cancel any pending requests; their result will not update the data or pending state. Any previously awaited promises will not resolve until this new request resolves. You can prevent this behaviour by setting the `dedupe` option, which will instead return the promise for the currently-executing request, if there is one.
By default, `refresh()` will cancel any pending requests their result will not update the data or pending state. Any previously awaited promises will not resolve until this new request resolves. You can prevent this behaviour by setting the `dedupe` option, which will instead return the promise for the currently-executing request, if there is one.
```js
refresh({ dedupe: true })
@ -387,3 +387,100 @@ export default defineComponent({
</template>
```
## Serialization
When fetching data from the `server` directory, the response is serialized using `JSON.stringify`. However, since serialization is limited to only JavaScript primitive types, Nuxt does its best to convert the return type of `$fetch` and `useFetch` to match the actual value.
::alert{icon=👉}
You can learn more about `JSON.stringify` limitations [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description).
::
### Example
```ts [server/api/foo.ts]
export default defineEventHandler(() => {
return new Date()
})
```
```vue [app.vue]
<script setup lang="ts">
// Type of `data` is inferred as string even though we returned a Date object
const { data } = await useFetch('/api/foo')
</script>
```
### Custom serializer function
To customize the serialization behavior, you can define a `toJSON` function on your returned object. If you define a `toJSON` method, Nuxt will respect the return type of the function and will not try to convert the types.
```ts [server/api/bar.ts]
export default defineEventHandler(() => {
const data = {
createdAt: new Date(),
toJSON() {
return {
createdAt: {
year: this.createdAt.getFullYear(),
month: this.createdAt.getMonth(),
day: this.createdAt.getDate(),
},
}
},
}
return data
})
```
```vue [app.vue]
<script setup lang="ts">
// Type of `data` is inferred as
// {
// createdAt: {
// year: number
// month: number
// day: number
// }
// }
const { data } = await useFetch('/api/bar')
</script>
```
### Using an alternative serializer
Nuxt does not currently support an alternative serializer to `JSON.stringify`. However, you can return your payload as a normal string and utilize the `toJSON` method to maintain type safety.
In the example below, we use [superjson](github.com/blitz-js/superjson) as our serializer.
```ts [server/api/superjson.ts]
import superjson from 'superjson'
export default defineEventHandler(() => {
const data = {
createdAt: new Date(),
// Workaround the type conversion
toJSON() {
return this
}
}
// Serialize the output to string, using superjson
return superjson.stringify(data) as unknown as typeof data
})
```
```vue [app.vue]
<script setup lang="ts">
import superjson from 'superjson'
// `date` is inferred as { createdAt: Date } and you can safely use the Date object methods
const { data } = await useFetch('/api/superjson', {
transform: (value) => {
return superjson.parse(value as unknown as string)
},
})
</script>
```