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