Queries are the primary way to fetch and cache data in ngrx-rtk-query. They automatically manage loading states, errors, caching, and re-fetching, all through Angular Signals for fine-grained reactivity.
ngrx-rtk-query provides two ways to access query state:
Fine-Grained (Recommended)
Whole Object
Access individual properties as signals for optimal change detection:
@Component({ template: ` <button [disabled]="postsQuery.isLoading()">Submit</button> `})export class MyComponent { postsQuery = useGetPostsQuery(); // Component only re-renders when isLoading changes}
Access the entire query state object:
@Component({ template: ` <button [disabled]="postsQuery().isLoading">Submit</button> `})export class MyComponent { postsQuery = useGetPostsQuery(); // Component re-renders on any query state change}
Use fine-grained access (query.isLoading()) for better performance. Your component will only re-render when that specific property changes.
import { skipToken } from 'ngrx-rtk-query';export class CharacterCardComponent { character = input<Character | undefined>(undefined); // Only fetches when character() is defined locationQuery = useGetLocationQuery( () => this.character()?.currentLocation ?? skipToken );}
When a query receives skipToken, it will not make a request and the query state will show isUninitialized: true.
export class PostDetailsComponent { readonly id = input.required<number>(); readonly postQuery = useGetPostQuery(this.id, { pollingInterval: 5000, // Refetch every 5 seconds refetchOnMountOrArgChange: true, // Refetch on mount or when id changes refetchOnFocus: true, // Refetch when window gains focus refetchOnReconnect: true, // Refetch when connection restored skip: false, // Skip the query (alternative to skipToken) });}
// ✅ Good - Automatically refetches when input changesexport class PostDetailsComponent { readonly id = input.required<number>(); readonly postQuery = useGetPostQuery(this.id);}