Skip to content

Commit 5e63c55

Browse files
refactor(angular-query): change query functions to accept an options object instead of an injector
change query functions to accept an options object instead of an injector so that it matches angular APIs such as effect and allows adding more options in the future. BREAKING CHANGE: The injector option has been replaced with an options object. The injector can now be provided with the options object. Closes #8711
1 parent 0511c82 commit 5e63c55

17 files changed

+96
-69
lines changed

examples/angular/devtools-panel/src/app/components/lazy-load-devtools-panel-example.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default class LazyLoadDevtoolsPanelExampleComponent {
4545
this.devtools = import(
4646
'@tanstack/angular-query-devtools-experimental'
4747
).then(({ injectDevtoolsPanel }) =>
48-
injectDevtoolsPanel(this.devToolsOptions, this.injector),
48+
injectDevtoolsPanel(this.devToolsOptions, { injector: this.injector }),
4949
)
5050
}
5151
}

packages/angular-query-devtools-experimental/src/inject-devtools-panel.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ import {
1212
import { TanstackQueryDevtoolsPanel } from '@tanstack/query-devtools'
1313
import {
1414
QueryClient,
15-
onlineManager,
15+
onlineManager
1616
} from '@tanstack/angular-query-experimental'
1717
import { isPlatformBrowser } from '@angular/common'
18+
import type {
19+
WithOptionalInjector
20+
} from '@tanstack/angular-query-experimental'
1821
import type { ElementRef } from '@angular/core'
1922
import type { DevtoolsErrorType } from '@tanstack/query-devtools'
2023

@@ -26,19 +29,19 @@ import type { DevtoolsErrorType } from '@tanstack/query-devtools'
2629
*
2730
* Consider `withDevtools` instead if you don't need this.
2831
* @param optionsFn - A function that returns devtools panel options.
29-
* @param injector - The Angular injector to use.
32+
* @param options - Additional configuration
3033
* @returns DevtoolsPanelRef
3134
* @see https://tanstack.com/query/v5/docs/framework/angular/devtools
3235
*/
3336
export function injectDevtoolsPanel(
3437
optionsFn: () => DevtoolsPanelOptions,
35-
injector?: Injector,
38+
options?: WithOptionalInjector,
3639
): DevtoolsPanelRef {
37-
!injector && assertInInjectionContext(injectDevtoolsPanel)
38-
const currentInjector = injector ?? inject(Injector)
40+
!options?.injector && assertInInjectionContext(injectDevtoolsPanel)
41+
const currentInjector = options?.injector ?? inject(Injector)
3942

4043
return runInInjectionContext(currentInjector, () => {
41-
const options = computed(optionsFn)
44+
const queryOptions = computed(optionsFn)
4245
let devtools: TanstackQueryDevtoolsPanel | null = null
4346

4447
const isBrowser = isPlatformBrowser(inject(PLATFORM_ID))
@@ -64,7 +67,7 @@ export function injectDevtoolsPanel(
6467
shadowDOMTarget,
6568
onClose,
6669
hostElement,
67-
} = options()
70+
} = queryOptions()
6871

6972
untracked(() => {
7073
if (!client) throw new Error('No QueryClient found')

packages/angular-query-experimental/src/__tests__/inject-infinite-query.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ describe('injectInfiniteQuery', () => {
8787
initialPageParam: 0,
8888
getNextPageParam: () => 12,
8989
}),
90-
TestBed.inject(Injector),
90+
{
91+
injector: TestBed.inject(Injector),
92+
},
9193
)
9294

9395
expect(query.status()).toBe('pending')

packages/angular-query-experimental/src/__tests__/inject-is-fetching.test.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ describe('injectIsFetching', () => {
6060

6161
test('can be used outside injection context when passing an injector', () => {
6262
expect(
63-
injectIsFetching(undefined, TestBed.inject(Injector)),
63+
injectIsFetching(
64+
undefined,
65+
{
66+
injector: TestBed.inject(Injector),
67+
},
68+
),
6469
).not.toThrow()
6570
})
6671
})

packages/angular-query-experimental/src/__tests__/inject-is-mutating.test.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ describe('injectIsMutating', () => {
6060

6161
test('can be used outside injection context when passing an injector', () => {
6262
expect(
63-
injectIsMutating(undefined, TestBed.inject(Injector)),
63+
injectIsMutating(
64+
undefined,
65+
{
66+
injector: TestBed.inject(Injector),
67+
},
68+
),
6469
).not.toThrow()
6570
})
6671
})

packages/angular-query-experimental/src/__tests__/inject-mutation.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,9 @@ describe('injectMutation', () => {
509509
mutationKey: ['injectionContextError'],
510510
mutationFn: () => Promise.resolve(),
511511
}),
512-
TestBed.inject(Injector),
512+
{
513+
injector: TestBed.inject(Injector),
514+
},
513515
)
514516
}).not.toThrow()
515517
})

packages/angular-query-experimental/src/__tests__/inject-query.test.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,9 @@ describe('injectQuery', () => {
638638
queryKey: ['manualInjector'],
639639
queryFn: simpleFetcher,
640640
}),
641-
TestBed.inject(Injector),
641+
{
642+
injector: TestBed.inject(Injector),
643+
},
642644
)
643645

644646
expect(query.status()).toBe('pending')

packages/angular-query-experimental/src/inject-infinite-query.ts

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { InfiniteQueryObserver } from '@tanstack/query-core'
22
import { createBaseQuery } from './create-base-query'
33
import { assertInjector } from './util/assert-injector/assert-injector'
4-
import type { Injector } from '@angular/core'
54
import type {
65
DefaultError,
76
InfiniteData,
@@ -11,7 +10,7 @@ import type {
1110
import type {
1211
CreateInfiniteQueryOptions,
1312
CreateInfiniteQueryResult,
14-
DefinedCreateInfiniteQueryResult,
13+
DefinedCreateInfiniteQueryResult, WithOptionalInjector,
1514
} from './types'
1615
import type {
1716
DefinedInitialDataInfiniteOptions,
@@ -22,7 +21,7 @@ import type {
2221
* Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
2322
* Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
2423
* @param optionsFn - A function that returns infinite query options.
25-
* @param injector - The Angular injector to use.
24+
* @param options - Additional configuration.
2625
* @returns The infinite query result.
2726
* @public
2827
*/
@@ -40,14 +39,14 @@ export function injectInfiniteQuery<
4039
TQueryKey,
4140
TPageParam
4241
>,
43-
injector?: Injector,
42+
options?: WithOptionalInjector,
4443
): DefinedCreateInfiniteQueryResult<TData, TError>
4544

4645
/**
4746
* Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
4847
* Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
4948
* @param optionsFn - A function that returns infinite query options.
50-
* @param injector - The Angular injector to use.
49+
* @param options - Additional configuration.
5150
* @returns The infinite query result.
5251
* @public
5352
*/
@@ -65,14 +64,14 @@ export function injectInfiniteQuery<
6564
TQueryKey,
6665
TPageParam
6766
>,
68-
injector?: Injector,
67+
options?: WithOptionalInjector,
6968
): CreateInfiniteQueryResult<TData, TError>
7069

7170
/**
7271
* Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
7372
* Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
7473
* @param optionsFn - A function that returns infinite query options.
75-
* @param injector - The Angular injector to use.
74+
* @param options - Additional configuration.
7675
* @returns The infinite query result.
7776
* @public
7877
*/
@@ -91,22 +90,22 @@ export function injectInfiniteQuery<
9190
TQueryKey,
9291
TPageParam
9392
>,
94-
injector?: Injector,
93+
options?: WithOptionalInjector,
9594
): CreateInfiniteQueryResult<TData, TError>
9695

9796
/**
9897
* Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
9998
* Infinite queries can additively "load more" data onto an existing set of data or "infinite scroll"
10099
* @param optionsFn - A function that returns infinite query options.
101-
* @param injector - The Angular injector to use.
100+
* @param options - Additional configuration.
102101
* @returns The infinite query result.
103102
* @public
104103
*/
105104
export function injectInfiniteQuery(
106105
optionsFn: () => CreateInfiniteQueryOptions,
107-
injector?: Injector,
106+
options?: WithOptionalInjector,
108107
) {
109-
return assertInjector(injectInfiniteQuery, injector, () =>
108+
return assertInjector(injectInfiniteQuery, options?.injector, () =>
110109
createBaseQuery(optionsFn, InfiniteQueryObserver as typeof QueryObserver),
111110
)
112111
}

packages/angular-query-experimental/src/inject-is-fetching.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@ import { DestroyRef, NgZone, inject, signal } from '@angular/core'
22
import { QueryClient, notifyManager } from '@tanstack/query-core'
33
import { assertInjector } from './util/assert-injector/assert-injector'
44
import type { QueryFilters } from '@tanstack/query-core'
5-
import type { Injector, Signal } from '@angular/core'
5+
import type { Signal } from '@angular/core'
6+
import type { WithOptionalInjector } from "./types";
67

78
/**
89
* Injects a signal that tracks the number of queries that your application is loading or
910
* fetching in the background.
1011
*
1112
* Can be used for app-wide loading indicators
1213
* @param filters - The filters to apply to the query.
13-
* @param injector - The Angular injector to use.
14+
* @param options - Additional configuration
1415
* @returns signal with number of loading or fetching queries.
1516
* @public
1617
*/
1718
export function injectIsFetching(
1819
filters?: QueryFilters,
19-
injector?: Injector,
20+
options?: WithOptionalInjector,
2021
): Signal<number> {
21-
return assertInjector(injectIsFetching, injector, () => {
22+
return assertInjector(injectIsFetching, options?.injector, () => {
2223
const destroyRef = inject(DestroyRef)
2324
const ngZone = inject(NgZone)
2425
const queryClient = inject(QueryClient)

packages/angular-query-experimental/src/inject-is-mutating.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@ import { DestroyRef, NgZone, inject, signal } from '@angular/core'
22
import { QueryClient, notifyManager } from '@tanstack/query-core'
33
import { assertInjector } from './util/assert-injector/assert-injector'
44
import type { MutationFilters } from '@tanstack/query-core'
5-
import type { Injector, Signal } from '@angular/core'
5+
import type { Signal } from '@angular/core'
6+
import type { WithOptionalInjector } from "./types";
67

78
/**
89
* Injects a signal that tracks the number of mutations that your application is fetching.
910
*
1011
* Can be used for app-wide loading indicators
1112
* @param filters - The filters to apply to the query.
12-
* @param injector - The Angular injector to use.
13+
* @param options - Additional configuration
1314
* @returns signal with number of fetching mutations.
1415
* @public
1516
*/
1617
export function injectIsMutating(
1718
filters?: MutationFilters,
18-
injector?: Injector,
19+
options?: WithOptionalInjector,
1920
): Signal<number> {
20-
return assertInjector(injectIsMutating, injector, () => {
21+
return assertInjector(injectIsMutating, options?.injector, () => {
2122
const destroyRef = inject(DestroyRef)
2223
const ngZone = inject(NgZone)
2324
const queryClient = inject(QueryClient)

packages/angular-query-experimental/src/inject-mutation-state.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import {
55
replaceEqualDeep,
66
} from '@tanstack/query-core'
77
import { assertInjector } from './util/assert-injector/assert-injector'
8-
import type { Injector, Signal } from '@angular/core'
8+
import type { Signal } from '@angular/core'
99
import type {
1010
Mutation,
1111
MutationCache,
1212
MutationFilters,
1313
MutationState,
1414
} from '@tanstack/query-core'
15+
import type { WithOptionalInjector } from "./types";
1516

1617
type MutationStateOptions<TResult = MutationState> = {
1718
filters?: MutationFilters
@@ -33,9 +34,7 @@ function getResult<TResult = MutationState>(
3334
/**
3435
* @public
3536
*/
36-
export interface InjectMutationStateOptions {
37-
injector?: Injector
38-
}
37+
export type InjectMutationStateOptions = WithOptionalInjector
3938

4039
/**
4140
* Injects a signal that tracks the state of all mutations.

packages/angular-query-experimental/src/inject-mutation.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ import { assertInjector } from './util/assert-injector/assert-injector'
1818
import { signalProxy } from './signal-proxy'
1919
import { noop, shouldThrowError } from './util'
2020
import type { DefaultError, MutationObserverResult } from '@tanstack/query-core'
21-
import type { CreateMutateFunction, CreateMutationResult } from './types'
21+
import type {CreateMutateFunction, CreateMutationResult, WithOptionalInjector} from './types'
2222
import type { CreateMutationOptions } from './mutation-options'
2323

2424
/**
2525
* Injects a mutation: an imperative function that can be invoked which typically performs server side effects.
2626
*
2727
* Unlike queries, mutations are not run automatically.
2828
* @param optionsFn - A function that returns mutation options.
29-
* @param injector - The Angular injector to use.
29+
* @param options - Additional configuration
3030
* @returns The mutation.
3131
* @public
3232
*/
@@ -37,9 +37,9 @@ export function injectMutation<
3737
TContext = unknown,
3838
>(
3939
optionsFn: () => CreateMutationOptions<TData, TError, TVariables, TContext>,
40-
injector?: Injector,
40+
options?: WithOptionalInjector,
4141
): CreateMutationResult<TData, TError, TVariables, TContext> {
42-
return assertInjector(injectMutation, injector, () => {
42+
return assertInjector(injectMutation, options?.injector, () => {
4343
const currentInjector = inject(Injector)
4444
const destroyRef = inject(DestroyRef)
4545
const ngZone = inject(NgZone)
@@ -104,7 +104,7 @@ export function injectMutation<
104104
})
105105
},
106106
{
107-
injector,
107+
injector: options?.injector,
108108
},
109109
)
110110

@@ -136,7 +136,7 @@ export function injectMutation<
136136
})
137137
},
138138
{
139-
injector,
139+
injector: options?.injector,
140140
},
141141
)
142142

packages/angular-query-experimental/src/inject-queries.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
signal,
1313
} from '@angular/core'
1414
import { assertInjector } from './util/assert-injector/assert-injector'
15-
import type { Injector, Signal } from '@angular/core'
15+
import type { Signal } from '@angular/core'
1616
import type {
1717
DefaultError,
1818
OmitKeyof,
@@ -24,6 +24,7 @@ import type {
2424
QueryObserverResult,
2525
ThrowOnError,
2626
} from '@tanstack/query-core'
27+
import type { WithOptionalInjector } from "./types";
2728

2829
// This defines the `CreateQueryOptions` that are accepted in `QueriesOptions` & `GetOptions`.
2930
// `placeholderData` function does not have a parameter
@@ -196,7 +197,7 @@ export type QueriesResults<
196197
* @param root0
197198
* @param root0.queries
198199
* @param root0.combine
199-
* @param injector
200+
* @param props
200201
* @public
201202
*/
202203
export function injectQueries<
@@ -210,9 +211,9 @@ export function injectQueries<
210211
queries: Signal<[...QueriesOptions<T>]>
211212
combine?: (result: QueriesResults<T>) => TCombinedResult
212213
},
213-
injector?: Injector,
214+
props?: WithOptionalInjector,
214215
): Signal<TCombinedResult> {
215-
return assertInjector(injectQueries, injector, () => {
216+
return assertInjector(injectQueries, props?.injector, () => {
216217
const destroyRef = inject(DestroyRef)
217218
const ngZone = inject(NgZone)
218219
const queryClient = inject(QueryClient)

packages/angular-query-experimental/src/inject-query-client.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Injector, inject } from '@angular/core'
22
import { QueryClient } from '@tanstack/query-core'
33
import type { InjectOptions } from '@angular/core'
4+
import type { WithOptionalInjector} from "./types";
45

56
/**
67
* Injects a `QueryClient` instance and allows passing a custom injector.
@@ -17,7 +18,7 @@ import type { InjectOptions } from '@angular/core'
1718
* ```
1819
*/
1920
export function injectQueryClient(
20-
injectOptions: InjectOptions & { injector?: Injector } = {},
21+
injectOptions: InjectOptions & WithOptionalInjector = {},
2122
) {
2223
return (injectOptions.injector ?? inject(Injector)).get(QueryClient)
2324
}

0 commit comments

Comments
 (0)