Query Options

Purpose and Scope

Query options are the configuration objects that describe a server-state read before TanStack Query observes, fetches, caches, or refetches it. A useful options object ties together the cache identity, the asynchronous data source, and the behavioral policy for a resource. In React documentation this pattern is commonly centralized with helpers such as queryOptions, while the supplied repository evidence demonstrates the same idea through Angular callbacks passed to injectQuery and application features passed to provideTanStackQuery. The practical goal is identical across adapters: define the request once, then reuse that definition wherever the app needs the same server state.

Sources: docs/framework/angular/guides/background-fetching-indicators.md, docs/framework/angular/reference/functions/provideTanStackQuery.md

The key problem this page solves is configuration drift. Without a reusable options pattern, a component, a route prefetch, an invalidation call, a global loading indicator, and devtools may all refer to the same backend resource in slightly different ways. TanStack Query works best when query keys become a stable cache contract and query functions hide transport details behind a promise-returning boundary. The Angular background-fetching example shows that even a small query declaration has the essential pieces: queryKey identifies the todos resource, queryFn fetches it, and the observer exposes pending, error, success, data, and fetching signals.

Sources: docs/framework/angular/guides/background-fetching-indicators.md

Relevant Source Files

  • docs/framework/angular/reference/functions/provideTanStackQuery.md — Defines the Angular provider entry point, its QueryClient parameter, optional QueryFeatures, withDevtools setup, InjectionToken optimization, and Provider[] return contract.
  • docs/community-resources.md — Lists ecosystem utilities such as Query Key Factory, GraphQL Code Generator, Orval, and React Query Kit that are relevant to standardized keys and typed reusable query APIs.
  • docs/config.json — Shows that the official docs organize this topic alongside framework guides, TypeScript, GraphQL, devtools, reactivity, SSR, and community resources.
  • docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md — Explains the promise-based queryFn contract, Angular HttpClient integration, observable conversion, and tradeoffs among fetch, HttpClient, and specialized clients.
  • docs/framework/angular/devtools.md — Documents withDevtools, production subpath behavior, loadDevtools options, and reactive option callbacks for tooling configuration.
  • docs/framework/angular/guides/background-fetching-indicators.md — Provides concrete injectQuery and injectIsFetching examples that consume query options and expose local and global background fetching state.

Core Primitives

The first primitive is QueryClient. It owns the caches, defaults, and coordination behavior that individual options participate in. The Angular reference defines provideTanStackQuery as the setup function that installs providers for an application and accepts either a QueryClient instance or an InjectionToken that provides one. This matters for reusable options because the same key and function are only truly shared when they run against the same client. If a lazy route uses an InjectionToken, the docs describe that as an advanced bundle optimization, not the default architecture most applications need.

Sources: docs/framework/angular/reference/functions/provideTanStackQuery.md

The second primitive is the query option object or factory. In Angular, injectQuery receives a callback that returns an object, giving the adapter a place to evaluate current values and construct options. In React-oriented codebases, the same architectural role is often filled by a queryOptions helper or a domain-level factory function. The framework syntax differs, but the source-level contract remains simple: build a typed description of the request and pass that description to observers, prefetching, cache reads, and invalidation workflows instead of copying the key and fetcher across files.

Sources: docs/framework/angular/guides/background-fetching-indicators.md, docs/config.json

The third primitive is queryFn. The Angular data-client guide states that TanStack Query fetching is built on Promises and is agnostic to the client used underneath. That means the option factory can wrap browser fetch, graphql-request, Angular HttpClient, a generated OpenAPI client, or another asynchronous library. When HttpClient returns observables, the example converts them with lastValueFrom before returning from queryFn. This keeps components backend-agnostic: they consume query state and data, while the option factory owns how data is requested and normalized into a promise.

Sources: docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md

System-to-Code Mapping

The repository evidence maps reusable query options across four layers. The application layer installs a QueryClient with provideTanStackQuery and may attach features such as devtools. The resource layer declares per-query options with injectQuery callbacks that return queryKey and queryFn. The transport layer is represented by the HttpClient guide, where queryFn converts asynchronous client results into promises. The visibility layer is represented by injectIsFetching and devtools, which inspect cache and fetching state rather than redefining requests. Keeping those layers separate lets teams reuse options without coupling data fetching, rendering, diagnostics, and bootstrapping together.

Sources: docs/framework/angular/reference/functions/provideTanStackQuery.md, docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md, docs/framework/angular/guides/background-fetching-indicators.md, docs/framework/angular/devtools.md

The documentation configuration reinforces that query option design is not an isolated reference trick. The docs navigation places framework getting-started material next to TypeScript, GraphQL, React Native, devtools, reactivity, SSR, and community resources. That structure is useful when deciding where an option factory should stop. Type inference questions belong with TypeScript material, transport-specific questions belong with GraphQL or HttpClient guidance, and inspection belongs with devtools. Community utilities can help standardize larger applications, but they should build on the same basic contract of stable keys and promise-returning functions.

Sources: docs/config.json, docs/community-resources.md

Execution Flow

A reusable option flow usually begins near the domain resource rather than in a component template. Define a factory for a resource such as todos, repository details, search results, or a user profile. The factory should accept only inputs that change cache identity or fetching behavior, then return a key and a query function for that resource. A component can observe those options, while route code or event handlers can use the same definition for preloading and cache work. The important design constraint is that key, fetcher, and policy move together, so the application does not accidentally create multiple cache entries for one logical request.

Sources: docs/framework/angular/guides/background-fetching-indicators.md

In Angular, the flow starts with application providers. Configure provideTanStackQuery with a QueryClient, and add optional features only at the application or feature boundary. Inside a component or service, inject any data-client dependencies needed by the query function, such as HttpClient. Then call injectQuery with a callback that returns the options object. If the client produces observables, convert them with lastValueFrom or firstValueFrom inside queryFn. That placement preserves the TanStack Query promise contract while still allowing Angular interceptors, testing helpers, PendingTasks awareness, and SSR request caching to operate through HttpClient.

Sources: docs/framework/angular/reference/functions/provideTanStackQuery.md, docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md

After the query is declared, option-driven state becomes useful in both local and global UI. The background-fetching guide renders Loading while the query is pending, an error message when it fails, data when it succeeds, and Refreshing when a successful query is fetching again in the background. A separate global component uses injectIsFetching to show that any query is currently fetching. That example illustrates the payoff of shared options: components, global indicators, invalidation, and devtools are all observing the same cache model rather than managing parallel request flags.

Sources: docs/framework/angular/guides/background-fetching-indicators.md, docs/framework/angular/devtools.md

Compact API and Options Reference

ComponentSource-level contract shown in evidenceHow it relates to reusable query options
provideTanStackQueryfunction provideTanStackQuery(queryClient, ...features): Provider[]Installs the QueryClient and optional features that all query option objects run against.
queryClient parameterQueryClient or InjectionTokenChooses the shared cache owner, with InjectionToken documented as an advanced lazy-loading optimization.
features parameter...QueryFeatures[]Adds application-level behavior such as devtools without mixing tooling into per-resource options.
injectQueryinjectQuery(() => ({ queryKey: ['todos'], queryFn: fetchTodos }))Consumes a callback that returns the query options object for an observed resource.
queryKeyExample key ['todos']Names the cache entry and should include every input that changes the result.
queryFnExample fetchTodos or a function returning lastValueFrom(http.get(...))Performs asynchronous fetching and must produce promise-compatible data for TanStack Query.
injectIsFetchinginjectIsFetching()Reads global fetching state produced by observed queries, without redefining individual options.
withDevtoolswithDevtools() or withDevtools(() => ({ loadDevtools }))Configures query inspection at provider setup time; loadDevtools may be 'auto', true, or false.

Sources: docs/framework/angular/reference/functions/provideTanStackQuery.md, docs/framework/angular/guides/background-fetching-indicators.md, docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md, docs/framework/angular/devtools.md

A minimal reusable query option should always name the resource and define how to fetch it. Common public query option fields include queryKey, queryFn, enabled, networkMode, initialData, placeholderData, refetch policies, retry behavior, select, staleTime, garbage-collection timing, structural sharing, metadata, and error-throwing behavior. The supplied repository examples show the minimum shape, while provider docs show where defaults and features are installed. Keep resource-specific decisions in the option factory, keep app-wide policy on the QueryClient, and keep tooling options in provider features rather than inside resource factories.

Sources: docs/framework/angular/guides/background-fetching-indicators.md, docs/framework/angular/reference/functions/provideTanStackQuery.md

Implementation Details and Edge Cases

Do not turn every call site into a second options factory. Reusable configuration works best when a base factory owns resource identity and stable behavior, while screens add only view-specific choices when necessary. For example, a todos option should own the todos key and fetch function, while a screen might choose how to render placeholder content or whether to select a subset for display. Conversely, retry policy or freshness timing may belong in shared defaults when the whole application treats a backend consistently. The provider-level QueryClient setup is the natural home for that application-wide behavior.

Sources: docs/framework/angular/reference/functions/provideTanStackQuery.md, docs/config.json

Transport clients are the most common edge case. The Angular HttpClient guide recommends HttpClient because it integrates with Angular testing, dependency-injection interceptors, PendingTasks, and SSR request caching. However, it currently returns observables, while TanStack Query expects promise-based fetching. A good options factory hides that mismatch by converting the observable inside queryFn, not at every component. The comparison table in the guide also makes the tradeoff explicit: fetch is small and native, HttpClient is integrated, and specialized libraries may be valuable for protocol-specific use cases such as GraphQL.

Sources: docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md

Devtools configuration is another edge case because it is environment-sensitive. The Angular devtools guide says devtools are included automatically only in development-mode bundles by default, while production use requires the production subpath and an explicit loadDevtools decision. The option can be omitted or set to 'auto', set to true to load in both development and production, or set to false to avoid loading. Keep this decision near application configuration, especially when using environment files or reactive signals, so resource-level query options remain focused on server-state identity and fetching.

Sources: docs/framework/angular/devtools.md

Next Steps

Start by identifying server resources that are read from more than one place, then give each one a small option factory with a stable key and a promise-returning function. Use those factories consistently in components, prefetching paths, cache reads, invalidation, and tests. For Angular applications, pair the pattern with provideTanStackQuery setup, the HttpClient conversion guide, background fetching indicators, and devtools. For larger teams, review the community utilities listed in the docs, especially Query Key Factory, React Query Kit, GraphQL Code Generator, and Orval, but keep the underlying contract simple and framework-agnostic.

Sources: docs/community-resources.md, docs/framework/angular/angular-httpclient-and-other-data-fetching-clients.md, docs/framework/angular/guides/background-fetching-indicators.md