11 KiB
id, title
| id | title |
|---|---|
| injectInfiniteQuery | injectInfiniteQuery |
Call Signature
function injectInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(injectInfiniteQueryFn, options?): DefinedCreateInfiniteQueryResult<TData, TError>;
Defined in: packages/angular-query-experimental/src/inject-infinite-query.ts:83
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<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
injectInfiniteQueryFn
() => DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
A function returning the DefinedInitialDataInfiniteOptions 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?
Additional configuration.
Returns
DefinedCreateInfiniteQueryResult<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 to share these options between injectInfiniteQuery and imperative APIs
like queryClient.fetchInfiniteQuery.
Example
@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
function injectInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(injectInfiniteQueryFn, options?): CreateInfiniteQueryResult<TData, TError>;
Defined in: packages/angular-query-experimental/src/inject-infinite-query.ts:239
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<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
injectInfiniteQueryFn
() => UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TData, TQueryKey, TPageParam>
A function returning the UndefinedInitialDataInfiniteOptions 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?
Additional configuration.
Returns
CreateInfiniteQueryResult<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 to share these options between injectInfiniteQuery and imperative APIs
like queryClient.fetchInfiniteQuery.
Examples
Fetching the next page from a button click:
@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:
@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:
@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
function injectInfiniteQuery<TQueryFnData, TError, TData, TQueryKey, TPageParam>(injectInfiniteQueryFn, options?): CreateInfiniteQueryResult<TData, TError>;
Defined in: packages/angular-query-experimental/src/inject-infinite-query.ts:267
This overload accepts the general CreateInfiniteQueryOptions 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<TQueryFnData, unknown>
TQueryKey
TQueryKey extends readonly unknown[] = readonly unknown[]
TPageParam
TPageParam = unknown
Parameters
injectInfiniteQueryFn
() => CreateInfiniteQueryOptions<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?
Additional configuration.
Returns
CreateInfiniteQueryResult<TData, TError>
The infinite query result.