diff --git a/README.md b/README.md index 0b8f949f6f3..68c42c5c802 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,26 @@ Still on **React Query v4**? No problem! Check out the v4 docs here: https://tan - [React Suspense](https://react.dev/reference/react/Suspense) + Fetch-As-You-Render Query Prefetching - Dedicated Devtools +## Partners + + + + + + + Speakeasy Logo + + + ## Contributing View the contributing guidelines [here](/CONTRIBUTING.md) @@ -52,3 +72,5 @@ View the contributing guidelines [here](/CONTRIBUTING.md) ### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/) + +[ diff --git a/examples/react/suspense/src/index.tsx b/examples/react/suspense/src/index.tsx index 814718dd783..2402fa9393a 100755 --- a/examples/react/suspense/src/index.tsx +++ b/examples/react/suspense/src/index.tsx @@ -70,18 +70,18 @@ function Example() { )} onReset={reset} > - Loading projects...}> - {showProjects ? ( - activeProject ? ( + {showProjects ? ( + Loading projects...}> + {activeProject ? ( ) : ( - ) - ) : null} - + )} + + ) : null} )} diff --git a/packages/angular-query-experimental/src/__tests__/provide-query-client.test.ts b/packages/angular-query-experimental/src/__tests__/provide-query-client.test.ts new file mode 100644 index 00000000000..5758a17457f --- /dev/null +++ b/packages/angular-query-experimental/src/__tests__/provide-query-client.test.ts @@ -0,0 +1,41 @@ +import { TestBed } from '@angular/core/testing' +import { describe, expect, test } from 'vitest' +import { + InjectionToken, + provideExperimentalZonelessChangeDetection, +} from '@angular/core' +import { QueryClient } from '@tanstack/query-core' +import { provideQueryClient } from '../providers' + +describe('provideQueryClient', () => { + test('should provide a QueryClient instance directly', () => { + const queryClient = new QueryClient() + + TestBed.configureTestingModule({ + providers: [ + provideExperimentalZonelessChangeDetection(), + provideQueryClient(queryClient), + ], + }) + + const providedQueryClient = TestBed.inject(QueryClient) + expect(providedQueryClient).toBe(queryClient) + }) + + test('should provide a QueryClient instance using an InjectionToken', () => { + const queryClient = new QueryClient() + const CUSTOM_QUERY_CLIENT = new InjectionToken('', { + factory: () => queryClient, + }) + + TestBed.configureTestingModule({ + providers: [ + provideExperimentalZonelessChangeDetection(), + provideQueryClient(CUSTOM_QUERY_CLIENT), + ], + }) + + const providedQueryClient = TestBed.inject(QueryClient) + expect(providedQueryClient).toBe(queryClient) + }) +}) diff --git a/packages/angular-query-experimental/src/__tests__/provide-tanstack-query.test.ts b/packages/angular-query-experimental/src/__tests__/provide-tanstack-query.test.ts new file mode 100644 index 00000000000..c35eb406a5c --- /dev/null +++ b/packages/angular-query-experimental/src/__tests__/provide-tanstack-query.test.ts @@ -0,0 +1,41 @@ +import { TestBed } from '@angular/core/testing' +import { describe, expect, test } from 'vitest' +import { + InjectionToken, + provideExperimentalZonelessChangeDetection, +} from '@angular/core' +import { QueryClient } from '@tanstack/query-core' +import { provideTanStackQuery } from '../providers' + +describe('provideTanStackQuery', () => { + test('should provide a QueryClient instance directly', () => { + const queryClient = new QueryClient() + + TestBed.configureTestingModule({ + providers: [ + provideExperimentalZonelessChangeDetection(), + provideTanStackQuery(queryClient), + ], + }) + + const providedQueryClient = TestBed.inject(QueryClient) + expect(providedQueryClient).toBe(queryClient) + }) + + test('should provide a QueryClient instance using an InjectionToken', () => { + const queryClient = new QueryClient() + const CUSTOM_QUERY_CLIENT = new InjectionToken('', { + factory: () => queryClient, + }) + + TestBed.configureTestingModule({ + providers: [ + provideExperimentalZonelessChangeDetection(), + provideTanStackQuery(CUSTOM_QUERY_CLIENT), + ], + }) + + const providedQueryClient = TestBed.inject(QueryClient) + expect(providedQueryClient).toBe(queryClient) + }) +}) diff --git a/packages/angular-query-experimental/src/providers.ts b/packages/angular-query-experimental/src/providers.ts index 98ea2e04ed8..0a7f784f4c0 100644 --- a/packages/angular-query-experimental/src/providers.ts +++ b/packages/angular-query-experimental/src/providers.ts @@ -1,6 +1,7 @@ import { DestroyRef, ENVIRONMENT_INITIALIZER, + InjectionToken, PLATFORM_ID, computed, effect, @@ -25,10 +26,19 @@ import type { * for the entire application. You can use `provideQueryClient` to provide a * different `QueryClient` instance for a part of the application. * @param queryClient - the `QueryClient` instance to provide. - * @public + * @returns a provider object that can be used to provide the `QueryClient` instance. */ -export function provideQueryClient(queryClient: QueryClient) { - return { provide: QueryClient, useValue: queryClient } +export function provideQueryClient( + queryClient: QueryClient | InjectionToken, +): Provider { + return { + provide: QueryClient, + useFactory: () => { + return queryClient instanceof InjectionToken + ? inject(queryClient) + : queryClient + }, + } } /** @@ -83,15 +93,14 @@ export function provideQueryClient(queryClient: QueryClient) { * } * ) * ``` - * @param queryClient - A `QueryClient` instance. + * @param queryClient - A `QueryClient` instance, or an `InjectionToken` which provides a `QueryClient`. * @param features - Optional features to configure additional Query functionality. * @returns A set of providers to set up TanStack Query. - * @public * @see https://tanstack.com/query/v5/docs/framework/angular/quick-start * @see withDevtools */ export function provideTanStackQuery( - queryClient: QueryClient, + queryClient: QueryClient | InjectionToken, ...features: Array ): EnvironmentProviders { return makeEnvironmentProviders([ @@ -100,10 +109,16 @@ export function provideTanStackQuery( // Do not use provideEnvironmentInitializer while Angular < v19 is supported provide: ENVIRONMENT_INITIALIZER, multi: true, - useValue: () => { - queryClient.mount() - // Unmount the query client on application destroy - inject(DestroyRef).onDestroy(() => queryClient.unmount()) + useFactory: () => { + const client = + queryClient instanceof InjectionToken + ? inject(queryClient) + : queryClient + return () => { + client.mount() + // Unmount the query client on application destroy + inject(DestroyRef).onDestroy(() => client.unmount()) + } }, }, features.map((feature) => feature.ɵproviders),