snapshot of https://github.com/TanStack/query.git (main, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
---
|
||||
id: defaultShouldDehydrateMutation
|
||||
title: defaultShouldDehydrateMutation
|
||||
---
|
||||
|
||||
```ts
|
||||
function defaultShouldDehydrateMutation(mutation): boolean;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/hydration.ts:177](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L177)
|
||||
|
||||
The default `shouldDehydrateMutation` predicate used by `dehydrate`. Only dehydrates mutations that are
|
||||
currently paused (e.g. paused by `networkMode` while offline).
|
||||
|
||||
## Parameters
|
||||
|
||||
### mutation
|
||||
|
||||
[`Mutation`](../classes/Mutation.md)
|
||||
|
||||
## Returns
|
||||
|
||||
`boolean`
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
id: defaultShouldDehydrateQuery
|
||||
title: defaultShouldDehydrateQuery
|
||||
---
|
||||
|
||||
```ts
|
||||
function defaultShouldDehydrateQuery(query): boolean;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/hydration.ts:185](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L185)
|
||||
|
||||
The default `shouldDehydrateQuery` predicate used by `dehydrate`. Only dehydrates queries whose status is
|
||||
`'success'`.
|
||||
|
||||
## Parameters
|
||||
|
||||
### query
|
||||
|
||||
[`Query`](../classes/Query.md)
|
||||
|
||||
## Returns
|
||||
|
||||
`boolean`
|
||||
43
docs/framework/angular/reference/functions/dehydrate.md
Normal file
43
docs/framework/angular/reference/functions/dehydrate.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: dehydrate
|
||||
title: dehydrate
|
||||
---
|
||||
|
||||
```ts
|
||||
function dehydrate(client, options): DehydratedState;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/hydration.ts:207](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L207)
|
||||
|
||||
Dehydrates a `QueryClient`'s cache (queries and mutations) into a plain, serializable `DehydratedState`,
|
||||
typically to embed in server-rendered markup and later restore into a client-side `QueryClient` via `hydrate`.
|
||||
Which queries/mutations are included, and how their data/errors are transformed, is controlled by `options`,
|
||||
falling back to the client's `dehydrate` default options, and finally to `defaultShouldDehydrateQuery` /
|
||||
`defaultShouldDehydrateMutation`.
|
||||
|
||||
## Parameters
|
||||
|
||||
### client
|
||||
|
||||
[`QueryClient`](../classes/QueryClient.md)
|
||||
|
||||
### options
|
||||
|
||||
[`DehydrateOptions`](../interfaces/DehydrateOptions.md) = `{}`
|
||||
|
||||
## Returns
|
||||
|
||||
[`DehydratedState`](../interfaces/DehydratedState.md)
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
await queryClient.prefetchQuery({
|
||||
queryKey: ['posts'],
|
||||
queryFn: getPosts,
|
||||
})
|
||||
|
||||
const dehydratedState = dehydrate(queryClient)
|
||||
```
|
||||
43
docs/framework/angular/reference/functions/dehydrateQuery.md
Normal file
43
docs/framework/angular/reference/functions/dehydrateQuery.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
id: dehydrateQuery
|
||||
title: dehydrateQuery
|
||||
---
|
||||
|
||||
```ts
|
||||
function dehydrateQuery(
|
||||
query,
|
||||
serializeData?,
|
||||
shouldRedactErrors?): DehydratedQuery;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/hydration.ts:148](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L148)
|
||||
|
||||
Dehydrates a single `Query` into a serializable `DehydratedQuery` snapshot. Note that most query config (e.g.
|
||||
`queryFn`, `staleTime`) is not dehydrated but instead meant to be configured again when consuming the
|
||||
de/rehydrated data, typically with `useQuery` on the client. If the query is still `pending`, its in-flight
|
||||
promise is dehydrated too so it can be resumed on the other side instead of re-fetched.
|
||||
|
||||
## Parameters
|
||||
|
||||
### query
|
||||
|
||||
[`Query`](../classes/Query.md)
|
||||
|
||||
The query to dehydrate.
|
||||
|
||||
### serializeData?
|
||||
|
||||
`TransformerFn`
|
||||
|
||||
Optional transform applied to `query.state.data` before it is included in the snapshot.
|
||||
|
||||
### shouldRedactErrors?
|
||||
|
||||
(`error`) => `boolean`
|
||||
|
||||
Optional predicate; if it returns `false` for the promise's rejection error, that
|
||||
error is kept as-is instead of being redacted.
|
||||
|
||||
## Returns
|
||||
|
||||
`DehydratedQuery`
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
id: experimental_streamedQuery
|
||||
title: experimental_streamedQuery
|
||||
---
|
||||
|
||||
```ts
|
||||
function experimental_streamedQuery<TQueryFnData, TData, TQueryKey>(streamFn): QueryFunction<TData, TQueryKey>;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/streamedQuery.ts:75](https://github.com/TanStack/query/blob/main/packages/query-core/src/streamedQuery.ts#L75)
|
||||
|
||||
This is a helper function to create a query function that streams data from an AsyncIterable.
|
||||
Data will be an Array of all the chunks received.
|
||||
The query will be in a 'pending' state until the first chunk of data is received, but will go to 'success' after that.
|
||||
The query will stay in fetchStatus 'fetching' until the stream ends.
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
### TData
|
||||
|
||||
`TData` = `TQueryFnData`[]
|
||||
|
||||
### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
## Parameters
|
||||
|
||||
### streamFn
|
||||
|
||||
`StreamedQueryParams`\<`TQueryFnData`, `TData`, `TQueryKey`\>
|
||||
|
||||
The function that returns an AsyncIterable to stream data from.
|
||||
|
||||
## Returns
|
||||
|
||||
[`QueryFunction`](../type-aliases/QueryFunction.md)\<`TData`, `TQueryKey`\>
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
await queryClient.query({
|
||||
queryKey: ['data'],
|
||||
queryFn: streamedQuery({
|
||||
streamFn: fetchDataInChunks,
|
||||
}),
|
||||
})
|
||||
```
|
||||
30
docs/framework/angular/reference/functions/hashKey.md
Normal file
30
docs/framework/angular/reference/functions/hashKey.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
id: hashKey
|
||||
title: hashKey
|
||||
---
|
||||
|
||||
```ts
|
||||
function hashKey(queryKey): string;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:284](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L284)
|
||||
|
||||
Default query & mutation keys hash function.
|
||||
Hashes the value into a stable hash.
|
||||
|
||||
## Parameters
|
||||
|
||||
### queryKey
|
||||
|
||||
readonly `unknown`[]
|
||||
|
||||
## Returns
|
||||
|
||||
`string`
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
// Object keys are sorted, so key order doesn't affect the hash:
|
||||
hashKey(['todos', { page: 1, filter: 'done' }]) // === '["todos",{"filter":"done","page":1}]'
|
||||
```
|
||||
49
docs/framework/angular/reference/functions/hydrate.md
Normal file
49
docs/framework/angular/reference/functions/hydrate.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: hydrate
|
||||
title: hydrate
|
||||
---
|
||||
|
||||
```ts
|
||||
function hydrate(
|
||||
client,
|
||||
dehydratedState,
|
||||
options?): void;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/hydration.ts:264](https://github.com/TanStack/query/blob/main/packages/query-core/src/hydration.ts#L264)
|
||||
|
||||
Restores a `DehydratedState` (as produced by `dehydrate`) into a `QueryClient`'s cache, typically to seed the
|
||||
client with data already fetched on the server. `mutations` and `queries` are each optional on `dehydratedState`.
|
||||
Queries not yet in the cache are built from the dehydrated snapshot; queries that already exist are only updated
|
||||
when the dehydrated data is newer than what's already cached. Newly built queries have their `fetchStatus` reset
|
||||
to `'idle'` so they don't hydrate stuck in a fetching state. If a dehydrated query still had an in-flight
|
||||
promise, it is resumed via `query.fetch()` (reusing that promise as `initialPromise`) rather than re-invoking
|
||||
`queryFn`.
|
||||
|
||||
## Parameters
|
||||
|
||||
### client
|
||||
|
||||
[`QueryClient`](../classes/QueryClient.md)
|
||||
|
||||
### dehydratedState
|
||||
|
||||
`Partial`\<[`DehydratedState`](../interfaces/DehydratedState.md)\>
|
||||
|
||||
### options?
|
||||
|
||||
[`HydrateOptions`](../interfaces/HydrateOptions.md)
|
||||
|
||||
## Returns
|
||||
|
||||
`void`
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
// dehydratedState was produced by `dehydrate` on the server
|
||||
// and sent to the client, e.g. embedded in server-rendered markup.
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
hydrate(queryClient, dehydratedState)
|
||||
```
|
||||
@@ -0,0 +1,285 @@
|
||||
---
|
||||
id: infiniteQueryOptions
|
||||
title: infiniteQueryOptions
|
||||
---
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): CreateInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/infinite-query-options.ts:181](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/infinite-query-options.ts#L181)
|
||||
|
||||
You can generally pass everything to `infiniteQueryOptions` that you can also pass to
|
||||
`injectInfiniteQuery`. These options can be shared across functions and imperative APIs such as
|
||||
`queryClient.fetchInfiniteQuery`. `options.queryKey` is required and is the query key to generate options
|
||||
for.
|
||||
|
||||
This overload is selected when `initialData` is set.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
#### TPageParam
|
||||
|
||||
`TPageParam` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`DefinedInitialDataInfiniteOptions`](../type-aliases/DefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
|
||||
|
||||
The [DefinedInitialDataInfiniteOptions](../type-aliases/DefinedInitialDataInfiniteOptions.md) to use — everything you can pass to
|
||||
`injectInfiniteQuery`, with `initialData` set.
|
||||
|
||||
### Returns
|
||||
|
||||
The same options object, typed so that `queryKey` carries the inferred data type.
|
||||
|
||||
### See
|
||||
|
||||
[injectInfiniteQuery](injectInfiniteQuery.md) to run an infinite query with these options.
|
||||
|
||||
### Remarks
|
||||
|
||||
See [injectInfiniteQuery](injectInfiniteQuery.md) for examples that fetch further pages, from a button click or
|
||||
automatically as the user scrolls.
|
||||
|
||||
### Example
|
||||
|
||||
```angular-ts
|
||||
import { infiniteQueryOptions, injectInfiniteQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const projectsOptions = infiniteQueryOptions({
|
||||
queryKey: ['projects'],
|
||||
queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
initialData: { pages: [], pageParams: [] },
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'projects',
|
||||
template: `
|
||||
<!-- `projectsQuery.data()` is never `undefined`, thanks to `initialData` — even if a
|
||||
refetch fails, so the list stays visible alongside the error. -->
|
||||
<ul>
|
||||
@for (page of projectsQuery.data().pages; track $index) {
|
||||
@for (project of page.projects; track project.id) {
|
||||
<li>{{ project.name }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
export class Projects {
|
||||
readonly projectsQuery = injectInfiniteQuery(() => projectsOptions)
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): OmitKeyof<CreateInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>, "queryFn"> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/infinite-query-options.ts:255](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/infinite-query-options.ts#L255)
|
||||
|
||||
You can generally pass everything to `infiniteQueryOptions` that you can also pass to
|
||||
`injectInfiniteQuery`. These options can be shared across functions and imperative APIs such as
|
||||
`queryClient.fetchInfiniteQuery`. `options.queryKey` is required and is the query key to generate options
|
||||
for.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
#### TPageParam
|
||||
|
||||
`TPageParam` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`UnusedSkipTokenInfiniteOptions`](../type-aliases/UnusedSkipTokenInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
|
||||
|
||||
The [UnusedSkipTokenInfiniteOptions](../type-aliases/UnusedSkipTokenInfiniteOptions.md) to use — everything you can pass to
|
||||
`injectInfiniteQuery`.
|
||||
|
||||
### Returns
|
||||
|
||||
The same options object, typed so that `queryKey` carries the inferred data type.
|
||||
|
||||
### Remarks
|
||||
|
||||
See [injectInfiniteQuery](injectInfiniteQuery.md) for examples that fetch further pages, from a button click or
|
||||
automatically as the user scrolls.
|
||||
|
||||
### Example
|
||||
|
||||
A parameterized factory, so the same options object can be reused per `postId`:
|
||||
```angular-ts
|
||||
import { infiniteQueryOptions, injectInfiniteQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const commentsOptions = (postId: string) =>
|
||||
infiniteQueryOptions({
|
||||
queryKey: ['post', postId, 'comments'],
|
||||
queryFn: ({ pageParam }) => fetchComments(postId, pageParam),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'comments',
|
||||
template: `
|
||||
@if (commentsQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (commentsQuery.isError()) {
|
||||
<span>Error: {{ commentsQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<ul>
|
||||
@for (page of commentsQuery.data().pages; track $index) {
|
||||
@for (comment of page.comments; track comment.id) {
|
||||
<li>{{ comment.text }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Comments {
|
||||
readonly postId = signal('1')
|
||||
readonly commentsQuery = injectInfiniteQuery(() => commentsOptions(this.postId()))
|
||||
}
|
||||
```
|
||||
|
||||
### See
|
||||
|
||||
[injectInfiniteQuery](injectInfiniteQuery.md) to run an infinite query with these options.
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function infiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>(options): CreateInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam> & object & QueryKeyWithDataTag<TQueryKey, InfiniteData<TQueryFnData, unknown>, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/infinite-query-options.ts:329](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/infinite-query-options.ts#L329)
|
||||
|
||||
You can generally pass everything to `infiniteQueryOptions` that you can also pass to
|
||||
`injectInfiniteQuery`. These options can be shared across functions and imperative APIs such as
|
||||
`queryClient.fetchInfiniteQuery`. `options.queryKey` is required and is the query key to generate options
|
||||
for.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
#### TPageParam
|
||||
|
||||
`TPageParam` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`UndefinedInitialDataInfiniteOptions`](../type-aliases/UndefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
|
||||
|
||||
The [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataInfiniteOptions.md) to use — everything you can pass to
|
||||
`injectInfiniteQuery`.
|
||||
|
||||
### Returns
|
||||
|
||||
The same options object, typed so that `queryKey` carries the inferred data type.
|
||||
|
||||
### Remarks
|
||||
|
||||
See [injectInfiniteQuery](injectInfiniteQuery.md) for examples that fetch further pages (from a button click or
|
||||
automatically as the user scrolls) and that use `skipToken` to disable the query until `postId` is set.
|
||||
|
||||
### Example
|
||||
|
||||
A parameterized factory, so the same options object can be reused per `postId`:
|
||||
```angular-ts
|
||||
import { infiniteQueryOptions, injectInfiniteQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const commentsOptions = (postId: string) =>
|
||||
infiniteQueryOptions({
|
||||
queryKey: ['post', postId, 'comments'],
|
||||
queryFn: ({ pageParam }) => fetchComments(postId, pageParam),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'comments',
|
||||
template: `
|
||||
@if (commentsQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (commentsQuery.isError()) {
|
||||
<span>Error: {{ commentsQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<ul>
|
||||
@for (page of commentsQuery.data().pages; track $index) {
|
||||
@for (comment of page.comments; track comment.id) {
|
||||
<li>{{ comment.text }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Comments {
|
||||
readonly postId = signal('1')
|
||||
readonly commentsQuery = injectInfiniteQuery(() => commentsOptions(this.postId()))
|
||||
}
|
||||
```
|
||||
|
||||
### See
|
||||
|
||||
[injectInfiniteQuery](injectInfiniteQuery.md) to run an infinite query with these options.
|
||||
@@ -0,0 +1,350 @@
|
||||
---
|
||||
id: injectInfiniteQuery
|
||||
title: injectInfiniteQuery
|
||||
---
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function injectInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(injectInfiniteQueryFn, options?): DefinedCreateInfiniteQueryResult<TData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-infinite-query.ts:83](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-infinite-query.ts#L83)
|
||||
|
||||
The options for `injectInfiniteQuery` are identical to `injectQuery`, with the addition of
|
||||
`initialPageParam`, `getNextPageParam`, `getPreviousPageParam`, and `maxPages`. Infinite queries can
|
||||
additively "load more" data onto an existing set of data, or "infinite scroll".
|
||||
|
||||
This overload is selected when `initialData` is set on the options returned by `injectInfiniteQueryFn`,
|
||||
so the resulting `data` signal is never `undefined` (unless a `select` changes `TData` to include `undefined`).
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
#### TPageParam
|
||||
|
||||
`TPageParam` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### injectInfiniteQueryFn
|
||||
|
||||
() => [`DefinedInitialDataInfiniteOptions`](../type-aliases/DefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
|
||||
|
||||
A function returning the [DefinedInitialDataInfiniteOptions](../type-aliases/DefinedInitialDataInfiniteOptions.md) to use —
|
||||
everything you can pass to `injectInfiniteQuery`, with `initialData` set. Similar to `computed` from
|
||||
Angular, this function runs in the reactive context, so signals read inside it drive the query.
|
||||
|
||||
#### options?
|
||||
|
||||
[`InjectInfiniteQueryOptions`](../interfaces/InjectInfiniteQueryOptions.md)
|
||||
|
||||
Additional configuration.
|
||||
|
||||
### Returns
|
||||
|
||||
[`DefinedCreateInfiniteQueryResult`](../type-aliases/DefinedCreateInfiniteQueryResult.md)\<`TData`, `TError`\>
|
||||
|
||||
The same signals as `injectQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
|
||||
`hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data().pages` and
|
||||
`data().pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
|
||||
`InfiniteData<TQueryFnData>` shape.
|
||||
|
||||
### Remarks
|
||||
|
||||
Keep in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default
|
||||
refetch behavior, resulting in outdated data. Make sure to call these functions only in response to user
|
||||
actions, or add conditions like `hasNextPage() && !isFetching()`.
|
||||
|
||||
### See
|
||||
|
||||
[infiniteQueryOptions](infiniteQueryOptions.md) to share these options between `injectInfiniteQuery` and imperative APIs
|
||||
like `queryClient.fetchInfiniteQuery`.
|
||||
|
||||
### Example
|
||||
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'projects',
|
||||
template: `
|
||||
<!-- `projectsQuery.data()` is never `undefined`, thanks to `initialData` — even if a
|
||||
refetch fails, so the list stays visible alongside the error. -->
|
||||
<ul>
|
||||
@for (page of projectsQuery.data().pages; track $index) {
|
||||
@for (project of page.projects; track project.id) {
|
||||
<li>{{ project.name }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
export class Projects {
|
||||
readonly projectsQuery = injectInfiniteQuery(() => ({
|
||||
queryKey: ['projects'],
|
||||
queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
initialData: { pages: [], pageParams: [] },
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function injectInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(injectInfiniteQueryFn, options?): CreateInfiniteQueryResult<TData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-infinite-query.ts:239](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-infinite-query.ts#L239)
|
||||
|
||||
Injects an infinite query: a declarative dependency on an asynchronous source of data that is tied to a
|
||||
unique key. Infinite queries can additively "load more" data onto an existing set of data, or
|
||||
"infinite scroll".
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
#### TPageParam
|
||||
|
||||
`TPageParam` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### injectInfiniteQueryFn
|
||||
|
||||
() => [`UndefinedInitialDataInfiniteOptions`](../type-aliases/UndefinedInitialDataInfiniteOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
|
||||
|
||||
A function returning the [UndefinedInitialDataInfiniteOptions](../type-aliases/UndefinedInitialDataInfiniteOptions.md) to use
|
||||
— everything you can pass to `injectInfiniteQuery`. Similar to `computed` from Angular, this function runs
|
||||
in the reactive context, so signals read inside it drive the query.
|
||||
|
||||
#### options?
|
||||
|
||||
[`InjectInfiniteQueryOptions`](../interfaces/InjectInfiniteQueryOptions.md)
|
||||
|
||||
Additional configuration.
|
||||
|
||||
### Returns
|
||||
|
||||
[`CreateInfiniteQueryResult`](../type-aliases/CreateInfiniteQueryResult.md)\<`TData`, `TError`\>
|
||||
|
||||
The same signals as `injectQuery`, with the addition of `fetchNextPage`, `fetchPreviousPage`,
|
||||
`hasNextPage`, `hasPreviousPage`, `isFetchingNextPage`, and `isFetchingPreviousPage`. `data().pages` and
|
||||
`data().pageParams` are also added, as long as a `select` doesn't change `TData` away from its default
|
||||
`InfiniteData<TQueryFnData>` shape.
|
||||
|
||||
### Remarks
|
||||
|
||||
Keep in mind that imperative fetch calls, such as `fetchNextPage`, may interfere with the default
|
||||
refetch behavior, resulting in outdated data. Make sure to call these functions only in response to user
|
||||
actions, or add conditions like `hasNextPage() && !isFetching()`. This is the only overload that accepts
|
||||
`queryFn: skipToken`, shown below.
|
||||
|
||||
### See
|
||||
|
||||
[infiniteQueryOptions](infiniteQueryOptions.md) to share these options between `injectInfiniteQuery` and imperative APIs
|
||||
like `queryClient.fetchInfiniteQuery`.
|
||||
|
||||
### Examples
|
||||
|
||||
Fetching the next page from a button click:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'projects-list',
|
||||
template: `
|
||||
<ul>
|
||||
@for (page of projectsQuery.data()?.pages; track $index) {
|
||||
@for (project of page.projects; track project.id) {
|
||||
<li>{{ project.name }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
<button
|
||||
[disabled]="!projectsQuery.hasNextPage() || projectsQuery.isFetching()"
|
||||
(click)="projectsQuery.fetchNextPage()"
|
||||
>
|
||||
Load More
|
||||
</button>
|
||||
`,
|
||||
})
|
||||
export class ProjectsList {
|
||||
readonly projectsQuery = injectInfiniteQuery(() => ({
|
||||
queryKey: ['projects'],
|
||||
queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
Fetching the next page automatically as the user scrolls, using an `IntersectionObserver` on a sentinel
|
||||
element after the list:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'projects-list',
|
||||
template: `
|
||||
<ul>
|
||||
@for (page of projectsQuery.data()?.pages; track $index) {
|
||||
@for (project of page.projects; track project.id) {
|
||||
<li>{{ project.name }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
<div #sentinel>{{ projectsQuery.isFetchingNextPage() ? 'Loading more...' : '' }}</div>
|
||||
`,
|
||||
})
|
||||
export class ProjectsList {
|
||||
readonly sentinel = viewChild<ElementRef<HTMLElement>>('sentinel')
|
||||
|
||||
readonly projectsQuery = injectInfiniteQuery(() => ({
|
||||
queryKey: ['projects'],
|
||||
queryFn: ({ pageParam }) => fetchProjects(pageParam),
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
}))
|
||||
|
||||
constructor() {
|
||||
effect((onCleanup) => {
|
||||
const sentinel = this.sentinel()?.nativeElement
|
||||
if (
|
||||
sentinel == null ||
|
||||
!this.projectsQuery.hasNextPage() ||
|
||||
this.projectsQuery.isFetching()
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const observer = new IntersectionObserver(([entry]) => {
|
||||
if (entry?.isIntersecting) this.projectsQuery.fetchNextPage()
|
||||
})
|
||||
observer.observe(sentinel)
|
||||
|
||||
onCleanup(() => observer.disconnect())
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A query that's disabled, type safe, until `postId` is set — pass `skipToken` as `queryFn` instead of
|
||||
setting `enabled: false`:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'comments',
|
||||
template: `
|
||||
@if (postId() == null) {
|
||||
Select a post
|
||||
} @else if (commentsQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (commentsQuery.isError()) {
|
||||
<span>Error: {{ commentsQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<ul>
|
||||
@for (page of commentsQuery.data().pages; track $index) {
|
||||
@for (comment of page.comments; track comment.id) {
|
||||
<li>{{ comment.text }}</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Comments {
|
||||
readonly postId = signal<string | undefined>(undefined)
|
||||
|
||||
readonly commentsQuery = injectInfiniteQuery(() => ({
|
||||
queryKey: ['post', this.postId(), 'comments'],
|
||||
queryFn:
|
||||
this.postId() != null
|
||||
? ({ pageParam }) => fetchComments(this.postId()!, pageParam)
|
||||
: skipToken,
|
||||
initialPageParam: 0,
|
||||
getNextPageParam: (lastPage) => lastPage.nextId,
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function injectInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(injectInfiniteQueryFn, options?): CreateInfiniteQueryResult<TData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-infinite-query.ts:267](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-infinite-query.ts#L267)
|
||||
|
||||
This overload accepts the general [CreateInfiniteQueryOptions](../interfaces/CreateInfiniteQueryOptions.md) shape rather than the
|
||||
`initialData`-aware overloads above, so whether `data` is defined can't be inferred from the call site —
|
||||
useful when wrapping `injectInfiniteQuery` in your own helper function that forwards caller-provided
|
||||
options.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = [`InfiniteData`](../interfaces/InfiniteData.md)\<`TQueryFnData`, `unknown`\>
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
#### TPageParam
|
||||
|
||||
`TPageParam` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### injectInfiniteQueryFn
|
||||
|
||||
() => [`CreateInfiniteQueryOptions`](../interfaces/CreateInfiniteQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`, `TPageParam`\>
|
||||
|
||||
A function that returns infinite query options. Similar to `computed` from
|
||||
Angular, this function runs in the reactive context, so signals read inside it drive the query.
|
||||
|
||||
#### options?
|
||||
|
||||
[`InjectInfiniteQueryOptions`](../interfaces/InjectInfiniteQueryOptions.md)
|
||||
|
||||
Additional configuration.
|
||||
|
||||
### Returns
|
||||
|
||||
[`CreateInfiniteQueryResult`](../type-aliases/CreateInfiniteQueryResult.md)\<`TData`, `TError`\>
|
||||
|
||||
The infinite query result.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: injectIsFetching
|
||||
title: injectIsFetching
|
||||
---
|
||||
|
||||
```ts
|
||||
function injectIsFetching(filters?, options?): Signal<number>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-is-fetching.ts:63](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-is-fetching.ts#L63)
|
||||
|
||||
Injects a signal that tracks the number of queries that your application is loading or fetching in the
|
||||
background (useful for app-wide loading indicators).
|
||||
|
||||
## Parameters
|
||||
|
||||
### filters?
|
||||
|
||||
[`QueryFilters`](../interfaces/QueryFilters.md)\<readonly `unknown`[]\>
|
||||
|
||||
The [QueryFilters](../interfaces/QueryFilters.md) to narrow down the matched queries.
|
||||
|
||||
### options?
|
||||
|
||||
[`InjectIsFetchingOptions`](../interfaces/InjectIsFetchingOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
## Returns
|
||||
|
||||
`Signal`\<`number`\>
|
||||
|
||||
A `Signal` with the number of queries that your application is currently loading or fetching in
|
||||
the background.
|
||||
|
||||
## Examples
|
||||
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'posts-fetching-indicator',
|
||||
template: `
|
||||
@if (isFetchingPosts()) {
|
||||
<span>Refreshing posts...</span>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class PostsFetchingIndicator {
|
||||
// How many queries matching the posts prefix are fetching?
|
||||
readonly isFetchingPosts = injectIsFetching({ queryKey: ['posts'] })
|
||||
}
|
||||
```
|
||||
|
||||
A global loading indicator for any query fetching in the background, not just the ones on screen:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'global-loading-indicator',
|
||||
template: `
|
||||
@if (isFetching()) {
|
||||
<div>Queries are fetching in the background...</div>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class GlobalLoadingIndicator {
|
||||
readonly isFetching = injectIsFetching()
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
id: injectIsMutating
|
||||
title: injectIsMutating
|
||||
---
|
||||
|
||||
```ts
|
||||
function injectIsMutating(filters?, options?): Signal<number>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-is-mutating.ts:46](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-is-mutating.ts#L46)
|
||||
|
||||
Injects a signal that tracks the number of mutations that your application currently has `pending`
|
||||
(useful for app-wide loading indicators).
|
||||
|
||||
## Parameters
|
||||
|
||||
### filters?
|
||||
|
||||
[`MutationFilters`](../interfaces/MutationFilters.md)\<`unknown`, `Error`, `unknown`, `unknown`\>
|
||||
|
||||
The [MutationFilters](../interfaces/MutationFilters.md) to narrow down the matched mutations.
|
||||
|
||||
### options?
|
||||
|
||||
[`InjectIsMutatingOptions`](../interfaces/InjectIsMutatingOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
## Returns
|
||||
|
||||
`Signal`\<`number`\>
|
||||
|
||||
A `Signal` with the number of mutations that your application currently has `pending`.
|
||||
|
||||
## Example
|
||||
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'posts-mutating-indicator',
|
||||
template: `
|
||||
@if (isMutatingPosts()) {
|
||||
<span>Saving posts...</span>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class PostsMutatingIndicator {
|
||||
// How many mutations matching the posts prefix are in progress?
|
||||
readonly isMutatingPosts = injectIsMutating({ mutationKey: ['posts'] })
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
id: injectIsRestoring
|
||||
title: injectIsRestoring
|
||||
---
|
||||
|
||||
```ts
|
||||
function injectIsRestoring(options?): Signal<boolean>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-is-restoring.ts:35](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-is-restoring.ts#L35)
|
||||
|
||||
Injects a signal that tracks whether a restore (e.g. from a persisted client, wired up via
|
||||
`provideIsRestoring`) is currently in progress. `injectQuery` and friends also check this internally to
|
||||
avoid race conditions between the restore and initializing queries.
|
||||
|
||||
## Parameters
|
||||
|
||||
### options?
|
||||
|
||||
`InjectIsRestoringOptions`
|
||||
|
||||
Additional configuration
|
||||
|
||||
## Returns
|
||||
|
||||
`Signal`\<`boolean`\>
|
||||
|
||||
A readonly `Signal<boolean>` — `true` while a restore is in progress, `false` otherwise (the
|
||||
default when no `provideIsRestoring` provider is registered).
|
||||
184
docs/framework/angular/reference/functions/injectMutation.md
Normal file
184
docs/framework/angular/reference/functions/injectMutation.md
Normal file
@@ -0,0 +1,184 @@
|
||||
---
|
||||
id: injectMutation
|
||||
title: injectMutation
|
||||
---
|
||||
|
||||
```ts
|
||||
function injectMutation<TData, TError, TVariables, TOnMutateResult>(injectMutationFn, options?): CreateMutationResult<TData, TError, TVariables, TOnMutateResult>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-mutation.ts:174](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-mutation.ts#L174)
|
||||
|
||||
Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects.
|
||||
`injectMutation` is the function for that. Unlike queries, mutations are not run automatically.
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### TData
|
||||
|
||||
`TData` = `unknown`
|
||||
|
||||
### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
### TVariables
|
||||
|
||||
`TVariables` = `void`
|
||||
|
||||
### TOnMutateResult
|
||||
|
||||
`TOnMutateResult` = `unknown`
|
||||
|
||||
## Parameters
|
||||
|
||||
### injectMutationFn
|
||||
|
||||
() => [`CreateMutationOptions`](../interfaces/CreateMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>
|
||||
|
||||
A function that returns mutation options. Similar to `computed` from Angular,
|
||||
this function runs in the reactive context, so signals read inside it drive the mutation's options.
|
||||
|
||||
### options?
|
||||
|
||||
[`InjectMutationOptions`](../interfaces/InjectMutationOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
## Returns
|
||||
|
||||
[`CreateMutationResult`](../type-aliases/CreateMutationResult.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>
|
||||
|
||||
The mutation result. Value fields are exposed as a `Signal` — read `data`/`error` by calling them
|
||||
(e.g. `mutation.data()`) — while function fields (`mutate`, `mutateAsync`, `reset`) are called directly,
|
||||
unchanged. `isSuccess`/`isError`/`isPending`/`isIdle` are type-guard methods you can call to narrow whether
|
||||
`data` is defined.
|
||||
|
||||
## Remarks
|
||||
|
||||
`mutate`/`mutateAsync` also accept per-call `onSuccess`/`onError`/`onSettled` callbacks as a
|
||||
second argument, useful for triggering call-site side effects (e.g. navigation) without coupling them to
|
||||
the shared mutation definition. Callbacks defined in `injectMutationFn` fire for every mutation; per-call
|
||||
callbacks fire only for the latest call you've made — `mutateAsync` gives you a promise per call instead,
|
||||
so you can await `Promise.all`/`Promise.allSettled` over several calls and see each one's outcome.
|
||||
|
||||
## See
|
||||
|
||||
[mutationOptions](mutationOptions.md) to share these options across multiple `injectMutation` call sites, or to look
|
||||
the mutation up elsewhere via its `mutationKey` (e.g. with `injectMutationState`).
|
||||
|
||||
## Examples
|
||||
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'todos',
|
||||
template: `
|
||||
@if (addMutation.isPending()) {
|
||||
<span>Adding todo...</span>
|
||||
} @else if (addMutation.isError()) {
|
||||
<div>An error occurred: {{ addMutation.error()?.message }}</div>
|
||||
}
|
||||
<button (click)="addMutation.mutate('Item')">Add</button>
|
||||
`,
|
||||
})
|
||||
export class Todos {
|
||||
readonly #queryClient = inject(QueryClient)
|
||||
|
||||
readonly addMutation = injectMutation(() => ({
|
||||
mutationFn: addTodo,
|
||||
onSuccess: () => this.#queryClient.invalidateQueries({ queryKey: ['todos'] }),
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
Optimistic update via `onMutate`, rolling back on `onError`:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'todos',
|
||||
template: `<button (click)="addMutation.mutate('Item')">Add</button>`,
|
||||
})
|
||||
export class Todos {
|
||||
readonly #queryClient = inject(QueryClient)
|
||||
|
||||
readonly addMutation = injectMutation(() => ({
|
||||
mutationFn: addTodo,
|
||||
onMutate: async (newTodo) => {
|
||||
await this.#queryClient.cancelQueries({ queryKey: ['todos'] })
|
||||
const previousTodos = this.#queryClient.getQueryData<Array<string>>(['todos'])
|
||||
|
||||
this.#queryClient.setQueryData<Array<string>>(['todos'], (old) => [
|
||||
...(old ?? []),
|
||||
newTodo,
|
||||
])
|
||||
|
||||
// Passed to `onError` as `onMutateResult` if the mutation fails.
|
||||
return { previousTodos }
|
||||
},
|
||||
onError: (_err, _newTodo, onMutateResult) => {
|
||||
this.#queryClient.setQueryData(['todos'], onMutateResult?.previousTodos)
|
||||
},
|
||||
onSettled: () => {
|
||||
this.#queryClient.invalidateQueries({ queryKey: ['todos'] })
|
||||
},
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
Callbacks passed per call to `mutate` only fire for the last call — `mutateAsync` gives you a promise per
|
||||
call instead, so you can wait for all of them when they succeed:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'todos',
|
||||
template: `
|
||||
<button (click)="handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])">Add all</button>
|
||||
`,
|
||||
})
|
||||
export class Todos {
|
||||
readonly #queryClient = inject(QueryClient)
|
||||
|
||||
readonly addMutation = injectMutation(() => ({
|
||||
mutationFn: addTodo,
|
||||
onSuccess: () => this.#queryClient.invalidateQueries({ queryKey: ['todos'] }),
|
||||
}))
|
||||
|
||||
async handleAddAll(todos: Array<string>) {
|
||||
try {
|
||||
await Promise.all(todos.map((todo) => this.addMutation.mutateAsync(todo)))
|
||||
} catch (error) {
|
||||
console.error('Failed to add todos:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If some of the mutations above can fail independently of the others, and you want to know which ones did —
|
||||
rather than losing that information the moment the first one rejects — swap `Promise.all` for
|
||||
`Promise.allSettled`:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'todos',
|
||||
template: `
|
||||
<button (click)="handleAddAll(['Todo 1', 'Todo 2', 'Todo 3'])">Add all</button>
|
||||
`,
|
||||
})
|
||||
export class Todos {
|
||||
readonly #queryClient = inject(QueryClient)
|
||||
|
||||
readonly addMutation = injectMutation(() => ({
|
||||
mutationFn: addTodo,
|
||||
onSuccess: () => this.#queryClient.invalidateQueries({ queryKey: ['todos'] }),
|
||||
}))
|
||||
|
||||
async handleAddAll(todos: Array<string>) {
|
||||
const addResults = await Promise.allSettled(
|
||||
todos.map((todo) => this.addMutation.mutateAsync(todo)),
|
||||
)
|
||||
|
||||
addResults.forEach((addResult, index) => {
|
||||
if (addResult.status === 'rejected') {
|
||||
console.error(`Failed to add "${todos[index]}":`, addResult.reason)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: injectMutationState
|
||||
title: injectMutationState
|
||||
---
|
||||
|
||||
```ts
|
||||
function injectMutationState<TResult>(injectMutationStateFn, options?): Signal<TResult[]>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-mutation-state.ts:106](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-mutation-state.ts#L106)
|
||||
|
||||
Injects a signal that gives you access to all mutations in the `MutationCache`. You can pass `filters`
|
||||
([MutationFilters](../interfaces/MutationFilters.md)) to narrow down your mutations, and `select` to transform the mutation state.
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### TResult
|
||||
|
||||
`TResult` = [`MutationState`](../interfaces/MutationState.md)\<`unknown`, `Error`, `unknown`, `unknown`\>
|
||||
|
||||
## Parameters
|
||||
|
||||
### injectMutationStateFn
|
||||
|
||||
() => `MutationStateOptions`\<`TResult`\>
|
||||
|
||||
A function returning the `filters` to narrow down matched mutations, and an
|
||||
optional `select` to transform the mutation state. Similar to `computed` from Angular, this function runs
|
||||
in the reactive context, so signals read inside it re-narrow the matched mutations.
|
||||
|
||||
### options?
|
||||
|
||||
[`InjectMutationStateOptions`](../interfaces/InjectMutationStateOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
## Returns
|
||||
|
||||
`Signal`\<`TResult`[]\>
|
||||
|
||||
A `Signal` with an Array of whatever `select` returns for each matching mutation.
|
||||
|
||||
## Examples
|
||||
|
||||
Get all variables of all running mutations:
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'pending-posts',
|
||||
template: `{{ pendingVariables().length }} posts saving...`,
|
||||
})
|
||||
export class PendingPosts {
|
||||
readonly pendingVariables = injectMutationState(() => ({
|
||||
filters: { status: 'pending' },
|
||||
select: (mutation) => mutation.state.variables,
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
Get all data for specific mutations via the `mutationKey`:
|
||||
```angular-ts
|
||||
const mutationKey = ['posts']
|
||||
|
||||
@Component({
|
||||
selector: 'posts',
|
||||
template: `
|
||||
<button (click)="createPost()">
|
||||
Create post ({{ savedPosts().length }} saved so far)
|
||||
</button>
|
||||
`,
|
||||
})
|
||||
export class Posts {
|
||||
// Some mutation that we want to get the state for
|
||||
readonly createPostMutation = injectMutation(() => ({
|
||||
mutationKey,
|
||||
mutationFn: createPosts,
|
||||
}))
|
||||
|
||||
readonly savedPosts = injectMutationState(() => ({
|
||||
// this mutation key needs to match the mutation key of the given mutation (see above)
|
||||
filters: { mutationKey, status: 'success' },
|
||||
select: (mutation) => mutation.state.data,
|
||||
}))
|
||||
|
||||
createPost() {
|
||||
this.createPostMutation.mutate(['New Post'])
|
||||
}
|
||||
}
|
||||
```
|
||||
263
docs/framework/angular/reference/functions/injectQuery.md
Normal file
263
docs/framework/angular/reference/functions/injectQuery.md
Normal file
@@ -0,0 +1,263 @@
|
||||
---
|
||||
id: injectQuery
|
||||
title: injectQuery
|
||||
---
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function injectQuery<TQueryFnData, TError, TData, TQueryKey>(injectQueryFn, options?): DefinedCreateQueryResult<TData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-query.ts:69](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-query.ts#L69)
|
||||
|
||||
This overload is selected when `initialData` is set on the options returned by `injectQueryFn`, so the
|
||||
resulting `data` signal is never `undefined` (unless a `select` changes `TData` to include `undefined`).
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `TQueryFnData`
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
### Parameters
|
||||
|
||||
#### injectQueryFn
|
||||
|
||||
() => [`DefinedInitialDataOptions`](../type-aliases/DefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
|
||||
|
||||
A function returning the [DefinedInitialDataOptions](../type-aliases/DefinedInitialDataOptions.md) to use — everything you
|
||||
can pass to `injectQuery`, with `initialData` set. Similar to `computed` from Angular, this function runs
|
||||
in the reactive context, so signals read inside it (in `queryKey`, `enabled`, etc.) drive the query.
|
||||
|
||||
#### options?
|
||||
|
||||
[`InjectQueryOptions`](../interfaces/InjectQueryOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
### Returns
|
||||
|
||||
[`DefinedCreateQueryResult`](../type-aliases/DefinedCreateQueryResult.md)\<`TData`, `TError`\>
|
||||
|
||||
The query result, typed so that `data` is never `undefined` (unless a `select` changes `TData` to
|
||||
include `undefined`).
|
||||
|
||||
### See
|
||||
|
||||
- https://tanstack.com/query/latest/docs/framework/angular/guides/queries
|
||||
- [queryOptions](queryOptions.md) to share these options between `injectQuery` and imperative APIs like
|
||||
`queryClient.fetchQuery`.
|
||||
|
||||
### Example
|
||||
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'posts',
|
||||
template: `
|
||||
<!-- `postsQuery.data()` is `Post[]`, never `undefined`, thanks to `initialData` — even if a
|
||||
refetch fails, so the list stays visible alongside the error. -->
|
||||
@if (postsQuery.isError()) {
|
||||
<span>Error: {{ postsQuery.error()?.message }}</span>
|
||||
}
|
||||
<ul>
|
||||
@for (post of postsQuery.data(); track post.id) {
|
||||
<li>{{ post.title }}</li>
|
||||
}
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
export class Posts {
|
||||
readonly postsQuery = injectQuery(() => ({
|
||||
queryKey: ['posts'],
|
||||
queryFn: fetchPosts,
|
||||
initialData: [],
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function injectQuery<TQueryFnData, TError, TData, TQueryKey>(injectQueryFn, options?): CreateQueryResult<TData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-query.ts:158](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-query.ts#L158)
|
||||
|
||||
Injects a query: a declarative dependency on an asynchronous source of data that is tied to a unique key.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `TQueryFnData`
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
### Parameters
|
||||
|
||||
#### injectQueryFn
|
||||
|
||||
() => [`UndefinedInitialDataOptions`](../type-aliases/UndefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
|
||||
|
||||
A function returning the [UndefinedInitialDataOptions](../type-aliases/UndefinedInitialDataOptions.md) to use — everything
|
||||
you can pass to `injectQuery`. Similar to `computed` from Angular, this function runs in the reactive
|
||||
context, so signals read inside it (in `queryKey`, `enabled`, etc.) drive the query.
|
||||
|
||||
#### options?
|
||||
|
||||
[`InjectQueryOptions`](../interfaces/InjectQueryOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
### Returns
|
||||
|
||||
[`CreateQueryResult`](../type-aliases/CreateQueryResult.md)\<`TData`, `TError`\>
|
||||
|
||||
The query result. `status()` is `'pending'` if there is no cached data to display, `'error'` if
|
||||
the last fetch attempt failed, or `'success'` if the query has data to display. `isPending`/`isSuccess`/
|
||||
`isError` are type-guard methods for convenience.
|
||||
|
||||
### See
|
||||
|
||||
- https://tanstack.com/query/latest/docs/framework/angular/guides/queries
|
||||
- [queryOptions](queryOptions.md) to share these options between `injectQuery` and imperative APIs like
|
||||
`queryClient.fetchQuery`.
|
||||
|
||||
### Examples
|
||||
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'posts',
|
||||
template: `
|
||||
@if (postsQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (postsQuery.isError()) {
|
||||
<span>Error: {{ postsQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<ul>
|
||||
@for (post of postsQuery.data(); track post.id) {
|
||||
<li>{{ post.title }}</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Posts {
|
||||
readonly postsQuery = injectQuery(() => ({
|
||||
queryKey: ['posts'],
|
||||
queryFn: fetchPosts,
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
Similar to `computed` from Angular, the function passed to `injectQuery` runs in the reactive context. In
|
||||
the example below, the query is automatically enabled and executed when the filter signal changes to a
|
||||
truthy value. When the filter signal changes back to a falsy value, the query is disabled.
|
||||
```angular-ts
|
||||
@Component({
|
||||
selector: 'posts',
|
||||
template: `
|
||||
<input [ngModel]="filter()" (ngModelChange)="filter.set($event)" />
|
||||
@if (postsQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (postsQuery.isError()) {
|
||||
<span>Error: {{ postsQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<ul>
|
||||
@for (post of postsQuery.data(); track post.id) {
|
||||
<li>{{ post.title }}</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Posts {
|
||||
readonly filter = signal('')
|
||||
|
||||
readonly postsQuery = injectQuery(() => ({
|
||||
queryKey: ['posts', this.filter()],
|
||||
queryFn: () => fetchPosts(this.filter()),
|
||||
// Signals can be combined with expressions
|
||||
enabled: !!this.filter(),
|
||||
}))
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function injectQuery<TQueryFnData, TError, TData, TQueryKey>(injectQueryFn, options?): CreateQueryResult<TData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-query.ts:185](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-query.ts#L185)
|
||||
|
||||
This overload accepts the general [CreateQueryOptions](../interfaces/CreateQueryOptions.md) shape rather than the `initialData`-aware
|
||||
overloads above, so whether `data` is defined can't be inferred from the call site — useful when wrapping
|
||||
`injectQuery` in your own helper function that forwards caller-provided options.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `TQueryFnData`
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
### Parameters
|
||||
|
||||
#### injectQueryFn
|
||||
|
||||
() => [`CreateQueryOptions`](../interfaces/CreateQueryOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
|
||||
|
||||
A function that returns query options. Similar to `computed` from Angular, this
|
||||
function runs in the reactive context, so signals read inside it (in `queryKey`, `enabled`, etc.) drive
|
||||
the query.
|
||||
|
||||
#### options?
|
||||
|
||||
[`InjectQueryOptions`](../interfaces/InjectQueryOptions.md)
|
||||
|
||||
Additional configuration
|
||||
|
||||
### Returns
|
||||
|
||||
[`CreateQueryResult`](../type-aliases/CreateQueryResult.md)\<`TData`, `TError`\>
|
||||
|
||||
The query result.
|
||||
|
||||
### See
|
||||
|
||||
https://tanstack.com/query/latest/docs/framework/angular/guides/queries
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
id: injectQueryClient
|
||||
title: injectQueryClient
|
||||
---
|
||||
|
||||
```ts
|
||||
function injectQueryClient(injectOptions): QueryClient;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-query-client.ts:18](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-query-client.ts#L18)
|
||||
|
||||
Injects a `QueryClient` instance and allows passing a custom injector.
|
||||
|
||||
## Parameters
|
||||
|
||||
### injectOptions
|
||||
|
||||
`InjectOptions` & `object` = `{}`
|
||||
|
||||
Type of the options argument to inject and optionally a custom injector.
|
||||
|
||||
## Returns
|
||||
|
||||
[`QueryClient`](../classes/QueryClient.md)
|
||||
|
||||
The `QueryClient` instance.
|
||||
|
||||
## Deprecated
|
||||
|
||||
Use `inject(QueryClient)` instead.
|
||||
If you need to get a `QueryClient` from a custom injector, use `injector.get(QueryClient)`.
|
||||
|
||||
**Example**
|
||||
```ts
|
||||
const queryClient = injectQueryClient();
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
id: isCancelledError
|
||||
title: isCancelledError
|
||||
---
|
||||
|
||||
```ts
|
||||
function isCancelledError(value): value is CancelledError;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/retryer.ts:90](https://github.com/TanStack/query/blob/main/packages/query-core/src/retryer.ts#L90)
|
||||
|
||||
## Parameters
|
||||
|
||||
### value
|
||||
|
||||
`any`
|
||||
|
||||
## Returns
|
||||
|
||||
`value is CancelledError`
|
||||
|
||||
## Deprecated
|
||||
|
||||
Use instanceof `CancelledError` instead.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
id: keepPreviousData
|
||||
title: keepPreviousData
|
||||
---
|
||||
|
||||
```ts
|
||||
function keepPreviousData<T>(previousData): T | undefined;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:493](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L493)
|
||||
|
||||
Intended to be passed as a query's `placeholderData` option, for example
|
||||
`placeholderData: keepPreviousData`. Instead of resetting the query's data to `undefined` while a new
|
||||
query key is fetching, it keeps displaying the previously fetched data until the new data arrives.
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### T
|
||||
|
||||
`T`
|
||||
|
||||
## Parameters
|
||||
|
||||
### previousData
|
||||
|
||||
`T` | `undefined`
|
||||
|
||||
## Returns
|
||||
|
||||
`T` \| `undefined`
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
new QueryObserver(queryClient, {
|
||||
queryKey: ['posts', page],
|
||||
queryFn: () => fetchPosts(page),
|
||||
placeholderData: keepPreviousData,
|
||||
})
|
||||
```
|
||||
38
docs/framework/angular/reference/functions/matchMutation.md
Normal file
38
docs/framework/angular/reference/functions/matchMutation.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
id: matchMutation
|
||||
title: matchMutation
|
||||
---
|
||||
|
||||
```ts
|
||||
function matchMutation(filters, mutation): boolean;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:237](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L237)
|
||||
|
||||
Checks whether a mutation matches the given [MutationFilters](../interfaces/MutationFilters.md).
|
||||
Every filter that is specified must match; filters that are left unspecified are ignored.
|
||||
If a `mutationKey` filter is provided but the mutation has no `mutationKey` of its own, it does not match.
|
||||
|
||||
## Parameters
|
||||
|
||||
### filters
|
||||
|
||||
[`MutationFilters`](../interfaces/MutationFilters.md)
|
||||
|
||||
### mutation
|
||||
|
||||
[`Mutation`](../classes/Mutation.md)\<`any`, `any`\>
|
||||
|
||||
## Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
const mutationCache = queryClient.getMutationCache()
|
||||
|
||||
const matchingMutations = mutationCache
|
||||
.getAll()
|
||||
.filter((mutation) => matchMutation({ mutationKey: ['addPost'] }, mutation))
|
||||
```
|
||||
37
docs/framework/angular/reference/functions/matchQuery.md
Normal file
37
docs/framework/angular/reference/functions/matchQuery.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: matchQuery
|
||||
title: matchQuery
|
||||
---
|
||||
|
||||
```ts
|
||||
function matchQuery(filters, query): boolean;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:175](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L175)
|
||||
|
||||
Checks whether a query matches the given [QueryFilters](../interfaces/QueryFilters.md).
|
||||
Every filter that is specified must match; filters that are left unspecified are ignored.
|
||||
|
||||
## Parameters
|
||||
|
||||
### filters
|
||||
|
||||
[`QueryFilters`](../interfaces/QueryFilters.md)
|
||||
|
||||
### query
|
||||
|
||||
[`Query`](../classes/Query.md)\<`any`, `any`, `any`, `any`\>
|
||||
|
||||
## Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
const queryCache = queryClient.getQueryCache()
|
||||
|
||||
const matchingQueries = queryCache
|
||||
.getAll()
|
||||
.filter((query) => matchQuery({ queryKey: ['posts'] }, query))
|
||||
```
|
||||
167
docs/framework/angular/reference/functions/mutationOptions.md
Normal file
167
docs/framework/angular/reference/functions/mutationOptions.md
Normal file
@@ -0,0 +1,167 @@
|
||||
---
|
||||
id: mutationOptions
|
||||
title: mutationOptions
|
||||
---
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function mutationOptions<TData, TError, TVariables, TOnMutateResult>(options): WithRequired<CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>, "mutationKey">;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/mutation-options.ts:40](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/mutation-options.ts#L40)
|
||||
|
||||
You can generally pass everything to `mutationOptions` that you can also pass to `injectMutation`. A
|
||||
`mutationKey` is required on this overload so the mutation can be looked up later, e.g. with
|
||||
`injectMutationState`.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TVariables
|
||||
|
||||
`TVariables` = `void`
|
||||
|
||||
#### TOnMutateResult
|
||||
|
||||
`TOnMutateResult` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`WithRequired`](../type-aliases/WithRequired.md)\<[`CreateMutationOptions`](../interfaces/CreateMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
|
||||
|
||||
The mutation options to use, identical to what you'd pass to `injectMutation`, with a
|
||||
required `mutationKey`.
|
||||
|
||||
### Returns
|
||||
|
||||
[`WithRequired`](../type-aliases/WithRequired.md)\<[`CreateMutationOptions`](../interfaces/CreateMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
|
||||
|
||||
The same options object, unchanged.
|
||||
|
||||
### See
|
||||
|
||||
[injectMutation](injectMutation.md) to run the mutation these options describe.
|
||||
|
||||
### Example
|
||||
|
||||
Looking the mutation up elsewhere via its `mutationKey`, e.g. for a global "saving…" indicator:
|
||||
```angular-ts
|
||||
import { mutationOptions, injectMutationState } from '@tanstack/angular-query-experimental'
|
||||
|
||||
const createPostOptions = mutationOptions({
|
||||
mutationKey: ['posts', 'create'],
|
||||
mutationFn: createPost,
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'saving-indicator',
|
||||
template: `
|
||||
@if (isCreatingPost()) {
|
||||
<span>Saving…</span>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class SavingIndicator {
|
||||
readonly #pendingCreates = injectMutationState(() => ({
|
||||
filters: { mutationKey: createPostOptions.mutationKey, status: 'pending' },
|
||||
}))
|
||||
readonly isCreatingPost = computed(() => this.#pendingCreates().length > 0)
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function mutationOptions<TData, TError, TVariables, TOnMutateResult>(options): Omit<CreateMutationOptions<TData, TError, TVariables, TOnMutateResult>, "mutationKey">;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/mutation-options.ts:98](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/mutation-options.ts#L98)
|
||||
|
||||
You can generally pass everything to `mutationOptions` that you can also pass to `injectMutation`. No
|
||||
`mutationKey` is required on this overload — use this when you don't need to target the mutation via a
|
||||
`mutationKey` filter later (e.g. with `injectMutationState`); it can still be observed through other
|
||||
filters, such as `status`.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TVariables
|
||||
|
||||
`TVariables` = `void`
|
||||
|
||||
#### TOnMutateResult
|
||||
|
||||
`TOnMutateResult` = `unknown`
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
`Omit`\<[`CreateMutationOptions`](../interfaces/CreateMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
|
||||
|
||||
The mutation options to use, identical to what you'd pass to `injectMutation`, without a
|
||||
`mutationKey`.
|
||||
|
||||
### Returns
|
||||
|
||||
`Omit`\<[`CreateMutationOptions`](../interfaces/CreateMutationOptions.md)\<`TData`, `TError`, `TVariables`, `TOnMutateResult`\>, `"mutationKey"`\>
|
||||
|
||||
The same options object, unchanged.
|
||||
|
||||
### See
|
||||
|
||||
[injectMutation](injectMutation.md) to run the mutation these options describe.
|
||||
|
||||
### Remarks
|
||||
|
||||
See the other overload's example for looking a mutation up via `injectMutationState`.
|
||||
|
||||
### Example
|
||||
|
||||
Sharing options across services, so `QueriesService` stays the single place a mutation is defined:
|
||||
```angular-ts
|
||||
import { mutationOptions, injectMutation } from '@tanstack/angular-query-experimental'
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class QueriesService {
|
||||
readonly #queryClient = inject(QueryClient)
|
||||
|
||||
updatePost(id: number) {
|
||||
return mutationOptions({
|
||||
mutationFn: (post: Partial<Post>) => putPost(id, post),
|
||||
onSuccess: (newPost) => this.#queryClient.setQueryData(['posts', id], newPost),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'post',
|
||||
template: `<button (click)="save()">Save</button>`,
|
||||
})
|
||||
export class Post {
|
||||
readonly queries = inject(QueriesService)
|
||||
readonly id = signal(0)
|
||||
readonly updatePostMutation = injectMutation(() => this.queries.updatePost(this.id()))
|
||||
|
||||
save() {
|
||||
this.updatePostMutation.mutate({ title: 'New Title' })
|
||||
}
|
||||
}
|
||||
```
|
||||
32
docs/framework/angular/reference/functions/noop.md
Normal file
32
docs/framework/angular/reference/functions/noop.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
id: noop
|
||||
title: noop
|
||||
---
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function noop(): void;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:119](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L119)
|
||||
|
||||
A function that does nothing.
|
||||
|
||||
### Returns
|
||||
|
||||
`void`
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function noop(): undefined;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:120](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L120)
|
||||
|
||||
A function that does nothing.
|
||||
|
||||
### Returns
|
||||
|
||||
`undefined`
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
id: partialMatchKey
|
||||
title: partialMatchKey
|
||||
---
|
||||
|
||||
```ts
|
||||
function partialMatchKey(a, b): boolean;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:300](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L300)
|
||||
|
||||
Checks if key `b` partially matches with key `a`.
|
||||
|
||||
## Parameters
|
||||
|
||||
### a
|
||||
|
||||
readonly `unknown`[]
|
||||
|
||||
### b
|
||||
|
||||
readonly `unknown`[]
|
||||
|
||||
## Returns
|
||||
|
||||
`boolean`
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
id: provideAngularQuery
|
||||
title: provideAngularQuery
|
||||
---
|
||||
|
||||
```ts
|
||||
function provideAngularQuery(queryClient): Provider[];
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/providers.ts:121](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/providers.ts#L121)
|
||||
|
||||
Sets up providers necessary to enable TanStack Query functionality for Angular applications.
|
||||
|
||||
Allows configuring a `QueryClient`.
|
||||
|
||||
## Parameters
|
||||
|
||||
### queryClient
|
||||
|
||||
[`QueryClient`](../classes/QueryClient.md)
|
||||
|
||||
A `QueryClient` instance.
|
||||
|
||||
## Returns
|
||||
|
||||
`Provider`[]
|
||||
|
||||
A set of providers to set up TanStack Query.
|
||||
|
||||
## See
|
||||
|
||||
https://tanstack.com/query/v5/docs/framework/angular/quick-start
|
||||
|
||||
## Deprecated
|
||||
|
||||
Use `provideTanStackQuery` instead.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
id: provideIsRestoring
|
||||
title: provideIsRestoring
|
||||
---
|
||||
|
||||
```ts
|
||||
function provideIsRestoring(isRestoring): Provider;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/inject-is-restoring.ts:48](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/inject-is-restoring.ts#L48)
|
||||
|
||||
Registers a provider for the restore state read by `injectIsRestoring`. Wire this up wherever you drive a
|
||||
restore yourself — e.g. a persist-client integration — so `injectQuery` and friends can defer subscribing
|
||||
to their observer (avoiding a race with the restore) until the restore signal flips back to `false`.
|
||||
|
||||
## Parameters
|
||||
|
||||
### isRestoring
|
||||
|
||||
`Signal`\<`boolean`\>
|
||||
|
||||
A readonly `Signal<boolean>` that tracks the restore state.
|
||||
|
||||
## Returns
|
||||
|
||||
`Provider`
|
||||
|
||||
A provider for the `isRestoring` signal.
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
id: provideQueryClient
|
||||
title: provideQueryClient
|
||||
---
|
||||
|
||||
```ts
|
||||
function provideQueryClient(queryClient): Provider;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/providers.ts:22](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/providers.ts#L22)
|
||||
|
||||
Usually [provideTanStackQuery](provideTanStackQuery.md) is used once to set up TanStack Query and the
|
||||
[`QueryClient`](https://tanstack.com/query/latest/docs/reference/QueryClient) for the entire application —
|
||||
it calls `provideQueryClient` internally. Use `provideQueryClient` directly to provide a different
|
||||
`QueryClient` instance for part of the application, or for unit testing.
|
||||
|
||||
## Parameters
|
||||
|
||||
### queryClient
|
||||
|
||||
A `QueryClient` instance, or an `InjectionToken` which provides a `QueryClient`.
|
||||
|
||||
[`QueryClient`](../classes/QueryClient.md) | `InjectionToken`\<[`QueryClient`](../classes/QueryClient.md)\>
|
||||
|
||||
## Returns
|
||||
|
||||
`Provider`
|
||||
|
||||
A provider object that can be used to provide the `QueryClient` instance.
|
||||
|
||||
## Example
|
||||
|
||||
Providing a test-only `QueryClient` in a component test, without wiring up `provideTanStackQuery`'s other
|
||||
defaults:
|
||||
```ts
|
||||
TestBed.configureTestingModule({
|
||||
providers: [provideQueryClient(new QueryClient())],
|
||||
})
|
||||
```
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: provideTanStackQuery
|
||||
title: provideTanStackQuery
|
||||
---
|
||||
|
||||
```ts
|
||||
function provideTanStackQuery(queryClient, ...features): Provider[];
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/providers.ts:102](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/providers.ts#L102)
|
||||
|
||||
Sets up providers necessary to enable TanStack Query functionality for Angular applications. Allows
|
||||
configuring a `QueryClient` and optional features such as developer tools.
|
||||
|
||||
## Parameters
|
||||
|
||||
### queryClient
|
||||
|
||||
A `QueryClient` instance, or an `InjectionToken` which provides a `QueryClient`.
|
||||
|
||||
[`QueryClient`](../classes/QueryClient.md) | `InjectionToken`\<[`QueryClient`](../classes/QueryClient.md)\>
|
||||
|
||||
### features
|
||||
|
||||
...[`QueryFeatures`](../type-aliases/QueryFeatures.md)[]
|
||||
|
||||
Optional features to configure additional Query functionality.
|
||||
|
||||
## Returns
|
||||
|
||||
`Provider`[]
|
||||
|
||||
A set of providers to set up TanStack Query.
|
||||
|
||||
## See
|
||||
|
||||
- https://tanstack.com/query/v5/docs/framework/angular/quick-start
|
||||
- withDevtools
|
||||
|
||||
## Examples
|
||||
|
||||
```ts
|
||||
import { provideTanStackQuery, QueryClient } from '@tanstack/angular-query-experimental'
|
||||
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [provideTanStackQuery(new QueryClient())],
|
||||
})
|
||||
```
|
||||
|
||||
The same, in an `NgModule`-based application:
|
||||
```ts
|
||||
import { provideTanStackQuery, QueryClient } from '@tanstack/angular-query-experimental'
|
||||
|
||||
@NgModule({
|
||||
declarations: [AppComponent],
|
||||
imports: [BrowserModule],
|
||||
providers: [provideTanStackQuery(new QueryClient())],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {}
|
||||
```
|
||||
|
||||
Enabling optional developer tools by adding `withDevtools` — by default, the tools are then loaded when
|
||||
your app is in development mode:
|
||||
```ts
|
||||
import {
|
||||
provideTanStackQuery,
|
||||
withDevtools,
|
||||
QueryClient,
|
||||
} from '@tanstack/angular-query-experimental'
|
||||
|
||||
bootstrapApplication(AppComponent, {
|
||||
providers: [provideTanStackQuery(new QueryClient(), withDevtools())],
|
||||
})
|
||||
```
|
||||
|
||||
Using an `InjectionToken` for the `QueryClient` — an advanced optimization that lets TanStack Query be
|
||||
absent from the main application bundle, useful for including it on lazy-loaded routes only while still
|
||||
sharing a `QueryClient`. This is a small optimization; for most applications it's preferable to provide
|
||||
the `QueryClient` in the main application config, as in the examples above:
|
||||
```ts
|
||||
export const MY_QUERY_CLIENT = new InjectionToken('', {
|
||||
factory: () => new QueryClient(),
|
||||
})
|
||||
|
||||
// In a lazy loaded route or lazy loaded component's providers array:
|
||||
providers: [provideTanStackQuery(MY_QUERY_CLIENT)]
|
||||
```
|
||||
38
docs/framework/angular/reference/functions/queryFeature.md
Normal file
38
docs/framework/angular/reference/functions/queryFeature.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
id: queryFeature
|
||||
title: queryFeature
|
||||
---
|
||||
|
||||
```ts
|
||||
function queryFeature<TFeatureKind>(kind, providers): QueryFeature<TFeatureKind>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/providers.ts:143](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/providers.ts#L143)
|
||||
|
||||
Helper function to create an object that represents a Query feature.
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### TFeatureKind
|
||||
|
||||
`TFeatureKind` *extends* `"Devtools"` \| `"PersistQueryClient"`
|
||||
|
||||
## Parameters
|
||||
|
||||
### kind
|
||||
|
||||
`TFeatureKind`
|
||||
|
||||
The kind of feature, e.g. `'Devtools'`.
|
||||
|
||||
### providers
|
||||
|
||||
`Provider`[]
|
||||
|
||||
The Angular providers this feature contributes to `provideTanStackQuery`.
|
||||
|
||||
## Returns
|
||||
|
||||
[`QueryFeature`](../interfaces/QueryFeature.md)\<`TFeatureKind`\>
|
||||
|
||||
A Query feature.
|
||||
274
docs/framework/angular/reference/functions/queryOptions.md
Normal file
274
docs/framework/angular/reference/functions/queryOptions.md
Normal file
@@ -0,0 +1,274 @@
|
||||
---
|
||||
id: queryOptions
|
||||
title: queryOptions
|
||||
---
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): Omit<CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryFn"> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/query-options.ts:151](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/query-options.ts#L151)
|
||||
|
||||
You can generally pass everything to `queryOptions` that you can also pass to `injectQuery`. These options
|
||||
can be shared across functions and imperative APIs such as `queryClient.fetchQuery`. `options.queryKey` is
|
||||
required and is the query key to generate options for.
|
||||
|
||||
This overload is selected when `initialData` is set, so the resulting `data` is never `undefined` (unless
|
||||
a `select` changes `TData` to include `undefined`).
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `TQueryFnData`
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`DefinedInitialDataOptions`](../type-aliases/DefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
|
||||
|
||||
The [DefinedInitialDataOptions](../type-aliases/DefinedInitialDataOptions.md) to use — everything you can pass to `injectQuery`,
|
||||
with `initialData` set.
|
||||
|
||||
### Returns
|
||||
|
||||
The same options object, typed so that `queryKey` carries the inferred data type.
|
||||
|
||||
### See
|
||||
|
||||
- [injectQuery](injectQuery.md) to run a query with these options.
|
||||
- [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
|
||||
|
||||
### Example
|
||||
|
||||
```angular-ts
|
||||
import { queryOptions, injectQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const postsOptions = queryOptions({
|
||||
queryKey: ['posts'],
|
||||
queryFn: fetchPosts,
|
||||
initialData: [],
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'posts',
|
||||
template: `
|
||||
<!-- `postsQuery.data()` is never `undefined`, thanks to `initialData` — even if a refetch
|
||||
fails, so the list stays visible alongside the error. -->
|
||||
@if (postsQuery.isError()) {
|
||||
<span>Error: {{ postsQuery.error()?.message }}</span>
|
||||
}
|
||||
<ul>
|
||||
@for (post of postsQuery.data(); track post.id) {
|
||||
<li>{{ post.title }}</li>
|
||||
}
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
export class Posts {
|
||||
readonly postsQuery = injectQuery(() => postsOptions)
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): OmitKeyof<CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "queryFn"> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/query-options.ts:200](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/query-options.ts#L200)
|
||||
|
||||
You can generally pass everything to `queryOptions` that you can also pass to `injectQuery`. These options
|
||||
can be shared across functions and imperative APIs such as `queryClient.fetchQuery`. `options.queryKey` is
|
||||
required and is the query key to generate options for.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `TQueryFnData`
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`UnusedSkipTokenOptions`](../type-aliases/UnusedSkipTokenOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
|
||||
|
||||
The [UnusedSkipTokenOptions](../type-aliases/UnusedSkipTokenOptions.md) to use — everything you can pass to `injectQuery`.
|
||||
|
||||
### Returns
|
||||
|
||||
The same options object, typed so that `queryKey` carries the inferred data type.
|
||||
|
||||
### See
|
||||
|
||||
- [injectQuery](injectQuery.md) to run a query with these options.
|
||||
- [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
|
||||
|
||||
### Example
|
||||
|
||||
A parameterized factory, so the same options object can be reused per `id`:
|
||||
```angular-ts
|
||||
import { queryOptions, injectQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const postOptions = (id: string) =>
|
||||
queryOptions({
|
||||
queryKey: ['post', id],
|
||||
queryFn: () => fetchPost(id),
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'post',
|
||||
template: `
|
||||
@if (postQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (postQuery.isError()) {
|
||||
<span>Error: {{ postQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<h1>{{ postQuery.data().title }}</h1>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Post {
|
||||
readonly id = signal('1')
|
||||
readonly postQuery = injectQuery(() => postOptions(this.id()))
|
||||
}
|
||||
```
|
||||
|
||||
## Call Signature
|
||||
|
||||
```ts
|
||||
function queryOptions<TQueryFnData, TError, TData, TQueryKey>(options): CreateQueryOptions<TQueryFnData, TError, TData, TQueryKey> & object & QueryKeyWithDataTag<TQueryKey, TQueryFnData, TError>;
|
||||
```
|
||||
|
||||
Defined in: [packages/angular-query-experimental/src/query-options.ts:281](https://github.com/TanStack/query/blob/main/packages/angular-query-experimental/src/query-options.ts#L281)
|
||||
|
||||
You can generally pass everything to `queryOptions` that you can also pass to `injectQuery`. These options
|
||||
can be shared across functions and imperative APIs such as `queryClient.fetchQuery`. `options.queryKey` is
|
||||
required and is the query key to generate options for.
|
||||
|
||||
### Type Parameters
|
||||
|
||||
#### TQueryFnData
|
||||
|
||||
`TQueryFnData` = `unknown`
|
||||
|
||||
#### TError
|
||||
|
||||
`TError` = `Error`
|
||||
|
||||
#### TData
|
||||
|
||||
`TData` = `TQueryFnData`
|
||||
|
||||
#### TQueryKey
|
||||
|
||||
`TQueryKey` *extends* readonly `unknown`[] = readonly `unknown`[]
|
||||
|
||||
### Parameters
|
||||
|
||||
#### options
|
||||
|
||||
[`UndefinedInitialDataOptions`](../type-aliases/UndefinedInitialDataOptions.md)\<`TQueryFnData`, `TError`, `TData`, `TQueryKey`\>
|
||||
|
||||
The [UndefinedInitialDataOptions](../type-aliases/UndefinedInitialDataOptions.md) to use — everything you can pass to `injectQuery`.
|
||||
|
||||
### Returns
|
||||
|
||||
The same options object, typed so that `queryKey` carries the inferred data type.
|
||||
|
||||
### See
|
||||
|
||||
- [injectQuery](injectQuery.md) to run a query with these options.
|
||||
- [The Query Options API](https://tkdodo.eu/blog/the-query-options-api) for more on this pattern.
|
||||
|
||||
### Remarks
|
||||
|
||||
This is the only overload that accepts `queryFn: skipToken`, shown below.
|
||||
|
||||
### Examples
|
||||
|
||||
A parameterized factory, so the same options object can be reused per `id`:
|
||||
```angular-ts
|
||||
import { queryOptions, injectQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const postOptions = (id: string) =>
|
||||
queryOptions({
|
||||
queryKey: ['post', id],
|
||||
queryFn: () => fetchPost(id),
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'post',
|
||||
template: `
|
||||
@if (postQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (postQuery.isError()) {
|
||||
<span>Error: {{ postQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<h1>{{ postQuery.data().title }}</h1>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Post {
|
||||
readonly id = signal('1')
|
||||
readonly postQuery = injectQuery(() => postOptions(this.id()))
|
||||
}
|
||||
```
|
||||
|
||||
A factory that disables the query, type safe, until `postId` is set:
|
||||
```angular-ts
|
||||
import { queryOptions, skipToken, injectQuery } from '@tanstack/angular-query-experimental'
|
||||
|
||||
export const postOptions = (postId: number | undefined) =>
|
||||
queryOptions({
|
||||
queryKey: ['post', postId],
|
||||
queryFn: postId != null ? () => fetchPost(postId) : skipToken,
|
||||
})
|
||||
|
||||
@Component({
|
||||
selector: 'post',
|
||||
template: `
|
||||
@if (postId() == null) {
|
||||
Select a post
|
||||
} @else if (postQuery.isPending()) {
|
||||
Loading...
|
||||
} @else if (postQuery.isError()) {
|
||||
<span>Error: {{ postQuery.error()?.message }}</span>
|
||||
} @else {
|
||||
<h1>{{ postQuery.data().title }}</h1>
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class Post {
|
||||
readonly postId = signal<number | undefined>(undefined)
|
||||
readonly postQuery = injectQuery(() => postOptions(this.postId()))
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: replaceEqualDeep
|
||||
title: replaceEqualDeep
|
||||
---
|
||||
|
||||
```ts
|
||||
function replaceEqualDeep<T>(
|
||||
a,
|
||||
b,
|
||||
depth?): T;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:339](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L339)
|
||||
|
||||
This function returns `a` if `b` is deeply equal.
|
||||
If not, it will replace any deeply equal children of `b` with those of `a`.
|
||||
This can be used for structural sharing between JSON values for example.
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### T
|
||||
|
||||
`T`
|
||||
|
||||
## Parameters
|
||||
|
||||
### a
|
||||
|
||||
`unknown`
|
||||
|
||||
### b
|
||||
|
||||
`T`
|
||||
|
||||
### depth?
|
||||
|
||||
`number`
|
||||
|
||||
## Returns
|
||||
|
||||
`T`
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: shouldThrowError
|
||||
title: shouldThrowError
|
||||
---
|
||||
|
||||
```ts
|
||||
function shouldThrowError<T>(throwOnError, params): boolean;
|
||||
```
|
||||
|
||||
Defined in: [packages/query-core/src/utils.ts:576](https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L576)
|
||||
|
||||
Resolves a `throwOnError` option to a boolean.
|
||||
If `throwOnError` is a function, it is called with `params` (e.g. the error and, depending on the caller,
|
||||
additional context such as the query or mutation) and its result is returned, allowing the throwing
|
||||
behavior to be decided per error. Otherwise, `throwOnError` itself is coerced to a boolean (`undefined`
|
||||
resolves to `false`).
|
||||
|
||||
## Type Parameters
|
||||
|
||||
### T
|
||||
|
||||
`T` *extends* (...`args`) => `boolean`
|
||||
|
||||
## Parameters
|
||||
|
||||
### throwOnError
|
||||
|
||||
`boolean` | `T` | `undefined`
|
||||
|
||||
### params
|
||||
|
||||
`Parameters`\<`T`\>
|
||||
|
||||
## Returns
|
||||
|
||||
`boolean`
|
||||
|
||||
## Example
|
||||
|
||||
```ts
|
||||
const throwOnError =
|
||||
query.state.error && typeof options.throwOnError === 'function'
|
||||
? shouldThrowError(options.throwOnError, [query.state.error, query])
|
||||
: options.throwOnError
|
||||
```
|
||||
Reference in New Issue
Block a user