From f01b7ce6d3fda1b638b28a61d606fa800291d7ec Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 22 Apr 2026 14:44:53 +0900 Subject: [PATCH 1/4] test(angular-query-experimental/injectIsFetching): switch main test to '@Component' + 'render' pattern (#10556) --- .../src/__tests__/inject-is-fetching.test.ts | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/angular-query-experimental/src/__tests__/inject-is-fetching.test.ts b/packages/angular-query-experimental/src/__tests__/inject-is-fetching.test.ts index f1d2861ab1..ad29c381bb 100644 --- a/packages/angular-query-experimental/src/__tests__/inject-is-fetching.test.ts +++ b/packages/angular-query-experimental/src/__tests__/inject-is-fetching.test.ts @@ -1,6 +1,11 @@ import { TestBed } from '@angular/core/testing' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Injector, provideZonelessChangeDetection } from '@angular/core' +import { + Component, + Injector, + provideZonelessChangeDetection, +} from '@angular/core' +import { render } from '@testing-library/angular' import { queryKey, sleep } from '@tanstack/query-test-utils' import { QueryClient, @@ -30,19 +35,29 @@ describe('injectIsFetching', () => { it('should return the number of fetching queries', async () => { const key = queryKey() - const isFetching = TestBed.runInInjectionContext(() => { - injectQuery(() => ({ + + @Component({ + template: `
fetching: {{ isFetching() }}
`, + }) + class Page { + readonly query = injectQuery(() => ({ queryKey: key, queryFn: () => sleep(100).then(() => 'Some data'), })) - return injectIsFetching() - }) + readonly isFetching = injectIsFetching() + } + + const rendered = await render(Page) + + expect(rendered.getByText('fetching: 0')).toBeInTheDocument() + + await vi.advanceTimersByTimeAsync(0) + rendered.fixture.detectChanges() + expect(rendered.getByText('fetching: 1')).toBeInTheDocument() - expect(isFetching()).toStrictEqual(0) - await vi.advanceTimersByTimeAsync(1) - expect(isFetching()).toStrictEqual(1) - await vi.advanceTimersByTimeAsync(100) - expect(isFetching()).toStrictEqual(0) + await vi.advanceTimersByTimeAsync(101) + rendered.fixture.detectChanges() + expect(rendered.getByText('fetching: 0')).toBeInTheDocument() }) describe('injection context', () => { From 0d2112c3e7d4776aa2c707d17f1a70e4207039ca Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 22 Apr 2026 15:36:56 +0900 Subject: [PATCH 2/4] test(angular-query-experimental/injectIsMutating): switch main test to '@Component' + 'render' pattern (#10557) --- .../src/__tests__/inject-is-mutating.test.ts | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/packages/angular-query-experimental/src/__tests__/inject-is-mutating.test.ts b/packages/angular-query-experimental/src/__tests__/inject-is-mutating.test.ts index 8433fef501..91d3e89afb 100644 --- a/packages/angular-query-experimental/src/__tests__/inject-is-mutating.test.ts +++ b/packages/angular-query-experimental/src/__tests__/inject-is-mutating.test.ts @@ -1,6 +1,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { TestBed } from '@angular/core/testing' -import { Injector, provideZonelessChangeDetection } from '@angular/core' +import { + Component, + Injector, + provideZonelessChangeDetection, +} from '@angular/core' +import { render } from '@testing-library/angular' import { queryKey, sleep } from '@tanstack/query-test-utils' import { QueryClient, @@ -30,25 +35,31 @@ describe('injectIsMutating', () => { it('should properly return isMutating state', async () => { const key = queryKey() - const [mutation, isMutating] = TestBed.runInInjectionContext(() => [ - injectMutation(() => ({ + + @Component({ + template: `
mutating: {{ isMutating() }}
`, + }) + class Page { + readonly mutation = injectMutation(() => ({ mutationKey: key, mutationFn: (params: { par1: string }) => sleep(10).then(() => params), - })), - injectIsMutating(), - ]) + })) + readonly isMutating = injectIsMutating() + } - expect(isMutating()).toBe(0) + const rendered = await render(Page) - mutation.mutate({ - par1: 'par1', - }) + expect(rendered.getByText('mutating: 0')).toBeInTheDocument() + + rendered.fixture.componentInstance.mutation.mutate({ par1: 'par1' }) - expect(isMutating()).toBe(0) await vi.advanceTimersByTimeAsync(0) - expect(isMutating()).toBe(1) + rendered.fixture.detectChanges() + expect(rendered.getByText('mutating: 1')).toBeInTheDocument() + await vi.advanceTimersByTimeAsync(11) - expect(isMutating()).toBe(0) + rendered.fixture.detectChanges() + expect(rendered.getByText('mutating: 0')).toBeInTheDocument() }) describe('injection context', () => { From e7de9090c8c20fc1baf6a438545df5b9b6d9701d Mon Sep 17 00:00:00 2001 From: Wonsuk Choi Date: Wed, 22 Apr 2026 15:56:27 +0900 Subject: [PATCH 3/4] test(angular-query-experimental/injectInfiniteQuery): switch main test to '@Component' + 'render' pattern (#10558) --- .../__tests__/inject-infinite-query.test.ts | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/packages/angular-query-experimental/src/__tests__/inject-infinite-query.test.ts b/packages/angular-query-experimental/src/__tests__/inject-infinite-query.test.ts index 45c1f6bc34..e3c3744d56 100644 --- a/packages/angular-query-experimental/src/__tests__/inject-infinite-query.test.ts +++ b/packages/angular-query-experimental/src/__tests__/inject-infinite-query.test.ts @@ -1,9 +1,13 @@ import { TestBed } from '@angular/core/testing' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' -import { Injector, provideZonelessChangeDetection } from '@angular/core' +import { + Component, + Injector, + provideZonelessChangeDetection, +} from '@angular/core' +import { render } from '@testing-library/angular' import { queryKey, sleep } from '@tanstack/query-test-utils' import { QueryClient, injectInfiniteQuery, provideTanStackQuery } from '..' -import { expectSignals } from './test-utils' describe('injectInfiniteQuery', () => { let queryClient: QueryClient @@ -25,42 +29,41 @@ describe('injectInfiniteQuery', () => { it('should properly execute infinite query', async () => { const key = queryKey() - const query = TestBed.runInInjectionContext(() => { - return injectInfiniteQuery(() => ({ + + @Component({ + template: ` +
status: {{ query.status() }}
+
pages: {{ query.data()?.pages?.join(', ') ?? 'none' }}
+ `, + }) + class Page { + readonly query = injectInfiniteQuery(() => ({ queryKey: key, queryFn: ({ pageParam }) => sleep(10).then(() => 'data on page ' + pageParam), initialPageParam: 0, getNextPageParam: () => 12, })) - }) + } - expectSignals(query, { - data: undefined, - status: 'pending', - }) + const rendered = await render(Page) - await vi.advanceTimersByTimeAsync(11) + expect(rendered.getByText('status: pending')).toBeInTheDocument() + expect(rendered.getByText('pages: none')).toBeInTheDocument() - expectSignals(query, { - data: { - pageParams: [0], - pages: ['data on page 0'], - }, - status: 'success', - }) + await vi.advanceTimersByTimeAsync(11) + rendered.fixture.detectChanges() + expect(rendered.getByText('status: success')).toBeInTheDocument() + expect(rendered.getByText('pages: data on page 0')).toBeInTheDocument() - void query.fetchNextPage() + rendered.fixture.componentInstance.query.fetchNextPage() await vi.advanceTimersByTimeAsync(11) - - expectSignals(query, { - data: { - pageParams: [0, 12], - pages: ['data on page 0', 'data on page 12'], - }, - status: 'success', - }) + rendered.fixture.detectChanges() + expect(rendered.getByText('status: success')).toBeInTheDocument() + expect( + rendered.getByText('pages: data on page 0, data on page 12'), + ).toBeInTheDocument() }) describe('injection context', () => { From 7d881354ffde0572370221bb3ba919c510ff5e54 Mon Sep 17 00:00:00 2001 From: Jan Aagaard Date: Wed, 22 Apr 2026 12:56:26 +0200 Subject: [PATCH 4/4] docs: Update the documentation for gcTime in setQueryData (#10559) Clarified the behavior of gcTime in setQueryData. https://bsky.app/profile/tkdodo.eu/post/3mk2z7ur7kc2m --- docs/reference/QueryClient.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/reference/QueryClient.md b/docs/reference/QueryClient.md index 13bde1ffad..a4783788b4 100644 --- a/docs/reference/QueryClient.md +++ b/docs/reference/QueryClient.md @@ -250,7 +250,7 @@ This distinction is more a "convenience" for ts devs that know which structure w ## `queryClient.setQueryData` -`setQueryData` is a synchronous function that can be used to immediately update a query's cached data. If the query does not exist, it will be created. **If the query is not utilized by a query hook in the default `gcTime` of 5 minutes, the query will be garbage collected**. To update multiple queries at once and match query keys partially, you need to use [`queryClient.setQueriesData`](#queryclientsetqueriesdata) instead. +`setQueryData` is a synchronous function that can be used to immediately update a query's cached data. If the query does not exist, it will be created. **If the query is not utilized by a query hook within the default `gcTime`, the query will be garbage collected. If the default `gcTime` has not been configured, it defaults to 5 minutes.** To update multiple queries at once and match query keys partially, you need to use [`queryClient.setQueriesData`](#queryclientsetqueriesdata) instead. > The difference between using `setQueryData` and `fetchQuery` is that `setQueryData` is sync and assumes that you already synchronously have the data available. If you need to fetch the data asynchronously, it's suggested that you either refetch the query key or use `fetchQuery` to handle the asynchronous fetch.