Short breakdown 👇
Angular Query is used for syncing server data with client applications.
- Without any unneeded abstractions.
Ideal for
grids
tables
listings
etc…
We have 2 packages to look at
ngneat/query
tanstack/angular-query-experimental
ngneat is unofficial adapter
- supporting RxJS & Signals by @ngneat_org @NetanelBasal
TanStack one is official
developed by @Arnoud_dv @tan_stack
for now supports only Signals
RxJS support planned for the future
Both are using TanStack Query Core.
🟨 Core Concepts 🟨
1. Queries
Declaratively manage data fetching.
Letting Angular Query handle the timing and specifics of server communication.
2. Mutations
Handle data modification
Integrating queries for a consistent data management
🧹 Cache & Cleanup 🧹
1. Cache Management
- Data maintenance and retrieval is handled by Query Client & Query Cache.
2. Query Keys
- A system for identifying and managing data dependencies across components.
3. SWR
- Ensures data freshness by smartly revalidating data behind the scenes without sacrificing performance.
💻 Significant DX improvements 💻
Reduced boilerplate Out of the box
Intelligent caching and data management strategies
Giant performance boost in writing async code
Pairs fantastic with component state management libraries
Basic usage with ngneat/query:
Service usage:
import { injectQuery } from '@ngneat/query';
@Injectable({ providedIn: 'root' })
export class TodosService {
#http = inject(HttpClient);
#query = injectQuery();
getTodos() {
return this.#query({
queryKey: ['todos'] as const,
queryFn: () => {
return this.http.get<Todo[]>(
'https://jsonplaceholder.typicode.com/todos',
);
},
});
}
}
Component usage with Observables:
@Component({
standalone: true,
template: `
@if (todos.result$ | async; as result) {
@if (result.isLoading) {
<p>Loading</p>
}
@if (result.isSuccess) {
<p>{{ result.data[0].title }}</p>
}
@if (result.isError) {
<p>Error</p>
}
}
`,
})
export class TodosPageComponent {
todos = inject(TodosService).getTodos();
}
Component usage with Signals:
@Component({
standalone: true,
template: `
@if (todos().isLoading) {
Loading
}
@if (todos().data; as data) {
<p>{{ data[0].title }}</p>
}
@if (todos().isError) {
<p>Error</p>
}
`,
})
export class TodosPageComponent {
todos = inject(TodosService).getTodos().result;
}
Docs:
ngneat: https://github.com/ngneat/query
TanStack: https://tanstack.com/query/latest/docs/framework/angular/overview
Follow me on X for more: https://twitter.com/DanielGlejzner
Top comments (9)
Sorry to say this, but I'd think it should be better to reword the title and the article a bit.
In its current state it sounds like there's something official from the Angular team called Angular Query.
I never heard about something like that (glad to be proved wrong, obviously), and I think that both projects are adapters for a third party lib, TanStack, that's not related to Angular in any way.
Angular Query is the official name for the adapter.
Still the article can be misleading.
IMHO, it would be better to clarify already in the breakdown you're writing about a third party lib for state management: Tanstack Query.
At the moment it looks like an angular feature, while it's just an adapter for a framework-agnostic library.
I appreciate your observation. Thanks.
Thank you
🙌
Angular Query simplifies server-client data synchronization, with ngneat/query and tanstack/angular-query-experimental packages. RxJS support planned. Efficiency for printer grids, tables, etc.
Hi Daniel Glejzner,
Excellent content, very useful.
Thanks for sharing.
Great