diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 413f98f52c..4702770445 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -204,6 +204,9 @@ export function useAsyncData< if (options.pick) { result = pick(result as any, options.pick) as DataT } + + nuxt.payload.data[key] = result + asyncData.data.value = result asyncData.error.value = null asyncData.status.value = 'success' @@ -212,7 +215,7 @@ export function useAsyncData< // If this request is cancelled, resolve to the latest request. if ((promise as any).cancelled) { return nuxt._asyncDataPromises[key] } - asyncData.error.value = error + asyncData.error.value = createError(error) as DataE asyncData.data.value = unref(options.default!()) asyncData.status.value = 'error' }) @@ -220,11 +223,7 @@ export function useAsyncData< if ((promise as any).cancelled) { return } asyncData.pending.value = false - nuxt.payload.data[key] = asyncData.data.value - if (asyncData.error.value) { - // We use `createError` and its .toJSON() property to normalize the error - nuxt.payload._errors[key] = createError(asyncData.error.value) - } + delete nuxt._asyncDataPromises[key] }) nuxt._asyncDataPromises[key] = promise diff --git a/test/nuxt/composables.test.ts b/test/nuxt/composables.test.ts index 1dea864fdd..f0d11b6be5 100644 --- a/test/nuxt/composables.test.ts +++ b/test/nuxt/composables.test.ts @@ -128,10 +128,20 @@ describe('useAsyncData', () => { }) it('should capture errors', async () => { - const { error, status, pending } = await useAsyncData(() => Promise.reject(new Error('test'))) + const { data, error, status, pending } = await useAsyncData('error-test', () => Promise.reject(new Error('test')), { default: () => 'default' }) + expect(data.value).toMatchInlineSnapshot('"default"') expect(error.value).toMatchInlineSnapshot('[Error: test]') expect(status.value).toBe('error') expect(pending.value).toBe(false) + expect(useNuxtApp().payload._errors['error-test']).toMatchInlineSnapshot('[Error: test]') + + // TODO: fix the below + // const { data: syncedData, error: syncedError, status: syncedStatus, pending: syncedPending } = await useAsyncData('error-test', () => ({}), { immediate: false }) + + // expect(syncedData.value).toEqual(null) + // expect(syncedError.value).toEqual(error.value) + // expect(syncedStatus.value).toEqual('idle') + // expect(syncedPending.value).toEqual(true) }) // https://github.com/nuxt/nuxt/issues/23411 @@ -182,6 +192,22 @@ describe('useAsyncData', () => { } `) }) + + it('should use default while pending', async () => { + const promise = useAsyncData(() => Promise.resolve('test'), { default: () => 'default' }) + const { data, pending } = promise + + expect(pending.value).toBe(true) + expect(data.value).toMatchInlineSnapshot('"default"') + + await promise + expect(data.value).toMatchInlineSnapshot('"test"') + }) + + it('should use default after reject', async () => { + const { data } = await useAsyncData(() => Promise.reject(new Error('test')), { default: () => 'default' }) + expect(data.value).toMatchInlineSnapshot('"default"') + }) }) describe('errors', () => {