diff --git a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts index a321b4c5c2..8a0c19a50e 100644 --- a/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts +++ b/packages/vue-query/src/__tests__/useInfiniteQuery.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { ref } from 'vue-demi' +import { skipToken } from '@tanstack/query-core' import { queryKey, sleep } from '@tanstack/query-test-utils' import { useInfiniteQuery } from '../useInfiniteQuery' import { infiniteQueryOptions } from '../infiniteQueryOptions' @@ -129,4 +130,58 @@ describe('useInfiniteQuery', () => { expect(hasNextPage.value).toBe(false) expect(isFetching.value).toBe(false) }) + + it('should keep initialData visible alongside the error when a refetch fails', async () => { + const key = queryKey() + const { data, status, isError } = useInfiniteQuery({ + queryKey: key, + queryFn: () => + sleep(10).then(() => Promise.reject(new Error('Some error'))), + initialData: { pages: [1], pageParams: [1] }, + getNextPageParam: (lastPage: number) => lastPage + 1, + initialPageParam: 0, + retry: false, + }) + + expect(data.value).toStrictEqual({ pages: [1], pageParams: [1] }) + expect(status.value).toStrictEqual('success') + expect(isError.value).toBe(false) + + await vi.advanceTimersByTimeAsync(10) + + expect(data.value).toStrictEqual({ pages: [1], pageParams: [1] }) + expect(status.value).toStrictEqual('error') + expect(isError.value).toBe(true) + }) + + it('should not fetch when queryFn is skipToken, and fetch once it is replaced', async () => { + const key = queryKey() + const postId = ref() + const queryFn = vi.fn(({ pageParam }: { pageParam: number }) => + sleep(10).then(() => `comments for ${postId.value} page ${pageParam}`), + ) + + const { data, isFetching } = useInfiniteQuery(() => ({ + queryKey: key, + queryFn: postId.value != null ? queryFn : skipToken, + initialPageParam: 0, + getNextPageParam: () => 12, + })) + + expect(isFetching.value).toBe(false) + + await vi.advanceTimersByTimeAsync(10) + expect(queryFn).not.toHaveBeenCalled() + expect(isFetching.value).toBe(false) + expect(data.value).toBeUndefined() + + postId.value = '1' + await vi.advanceTimersByTimeAsync(10) + + expect(queryFn).toHaveBeenCalledTimes(1) + expect(data.value).toStrictEqual({ + pages: ['comments for 1 page 0'], + pageParams: [0], + }) + }) }) diff --git a/packages/vue-query/src/__tests__/useQuery.test.ts b/packages/vue-query/src/__tests__/useQuery.test.ts index a648d3b001..099d48daa5 100644 --- a/packages/vue-query/src/__tests__/useQuery.test.ts +++ b/packages/vue-query/src/__tests__/useQuery.test.ts @@ -537,6 +537,32 @@ describe('useQuery', () => { }) }) + it('should keep initialData visible alongside the error when a refetch fails', async () => { + const key = queryKey() + + const query = useQuery({ + queryKey: key, + queryFn: () => + sleep(10).then(() => Promise.reject(new Error('Some error'))), + initialData: 'seeded data', + retry: false, + }) + + expect(query).toMatchObject({ + status: { value: 'success' }, + data: { value: 'seeded data' }, + isError: { value: false }, + }) + + await vi.advanceTimersByTimeAsync(10) + + expect(query).toMatchObject({ + status: { value: 'error' }, + data: { value: 'seeded data' }, + isError: { value: true }, + }) + }) + it('should keep the previous page visible while the next page loads with keepPreviousData', async () => { const key = queryKey() const page = ref(0)