Skip to content

Commit

Permalink
feat(nuxt): support async transforms for data composables (#26154)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Mar 8, 2024
1 parent 4023f7c commit 0cc7f29
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 5 deletions.
2 changes: 1 addition & 1 deletion docs/3.api/2.composables/use-async-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ type AsyncDataOptions<DataT> = {
deep?: boolean
dedupe?: 'cancel' | 'defer'
default?: () => DataT | Ref<DataT> | null
transform?: (input: DataT) => DataT
transform?: (input: DataT) => DataT | Promise<DataT>
pick?: string[]
watch?: WatchSource[]
getCachedData?: (key: string) => DataT
Expand Down
2 changes: 1 addition & 1 deletion docs/3.api/2.composables/use-fetch.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ type UseFetchOptions<DataT> = {
deep?: boolean
dedupe?: 'cancel' | 'defer'
default?: () => DataT
transform?: (input: DataT) => DataT
transform?: (input: DataT) => DataT | Promise<DataT>
pick?: string[]
watch?: WatchSource[] | false
}
Expand Down
6 changes: 3 additions & 3 deletions packages/nuxt/src/app/composables/asyncData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { asyncDataDefaults } from '#build/nuxt.config.mjs'

export type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'

export type _Transform<Input = any, Output = any> = (input: Input) => Output
export type _Transform<Input = any, Output = any> = (input: Input) => Output | Promise<Output>

export type PickFrom<T, K extends Array<string>> = T extends Array<any>
? T
Expand Down Expand Up @@ -283,13 +283,13 @@ export function useAsyncData<
reject(err)
}
})
.then((_result) => {
.then(async (_result) => {
// If this request is cancelled, resolve to the latest request.
if ((promise as any).cancelled) { return nuxtApp._asyncDataPromises[key] }

let result = _result as unknown as DataT
if (options.transform) {
result = options.transform(_result)
result = await options.transform(_result)
}
if (options.pick) {
result = pick(result as any, options.pick) as DataT
Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/basic-types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,16 @@ describe('composables', () => {
expectTypeOf(useLazyAsyncData<string>(() => $fetch('/test'), { default: () => 'test', transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string>>()
})

it('supports asynchronous transform', () => {
const { data } = useAsyncData('test', () => $fetch('/test') as Promise<{ foo: 'bar' }>, {
async transform (data) {
await Promise.resolve()
return data.foo
}
})
expectTypeOf(data).toEqualTypeOf<Ref<'bar' | null>>()
})

it('infer request url string literal from server/api routes', () => {
// request can accept dynamic string type
const dynamicStringUrl = 'https://example.com/api'
Expand Down

0 comments on commit 0cc7f29

Please sign in to comment.