
Angular Query
- 159 installs
- 6 repo stars
- Updated April 4, 2026
- oguzhan18/angular-ecosystem-skills
Implement cached async data fetching, mutations, and loading/error states in Angular apps using query-style patterns aligned with modern resource APIs.
About
Guides Angular developers through query-style async data management: defining fetchers, caching policies, stale-while-revalidate behavior, mutation side effects, and component bindings so lists, detail views, and forms stay consistent with server truth.
- Declarative async state with loading and error handling
- Cache invalidation and refetch strategies
- Mutation flows with optimistic updates
- Pagination and dependent query coordination
- Integration with Angular change detection and signals
Angular Query by the numbers
- 159 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #938 of 2,245 Frontend Development skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/oguzhan18/angular-ecosystem-skills --skill angular-queryAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 159 |
|---|---|
| repo stars | ★ 6 |
| Last updated | April 4, 2026 |
| Repository | oguzhan18/angular-ecosystem-skills ↗ |
What it does
Implement cached async data fetching, mutations, and loading/error states in Angular apps using query-style patterns aligned with modern resource APIs.
Files
@tanstack/angular-query-experimental
Version: 5.x (2025) Tags: Data Fetching, Server State, Caching, TanStack Query
References: Docs • GitHub • npm
API Changes
This section documents version-specific API changes.
- NEW: Angular Query v5 — Signal-based API for TanStack Query source
- NEW:
injectQuery— Signal-based query injection
- NEW:
injectMutation— Signal-based mutation injection
- NEW: Query options pattern — Service-based query configuration
- NEW: DevTools integration — Angular Query DevTools for debugging
Best Practices
- Install and setup
npm install @tanstack/angular-query-experimentalimport { provideHttpClient } from '@angular/common/http';
import { provideTanStackQuery } from '@tanstack/angular-query-experimental';
import { QueryClient } from '@tanstack/query-core';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(),
provideTanStackQuery(new QueryClient())
]
};- Use injectQuery for data fetching
import { injectQuery } from '@tanstack/angular-query-experimental';
@Component({})
export class TodosComponent {
private http = inject(HttpClient);
query = injectQuery(() => ({
queryKey: ['todos'],
queryFn: () => lastValueFrom(this.http.get<Todo[]>('/api/todos'))
}));
}- Use in templates with signals
@Component({
template: `
@if (query.isPending()) {
Loading...
} @else if (query.isError()) {
Error: {{ query.error().message }}
} @else {
@for (todo of query.data(); track todo.id) {
{{ todo.title }}
}
}
`
})
export class TodosComponent {
query = injectQuery(() => ({ ... }));
}- Use mutations for data modification
import { injectMutation, injectQueryClient } from '@tanstack/angular-query-experimental';
@Component({})
export class AddTodoComponent {
private http = inject(HttpClient);
private queryClient = injectQueryClient();
mutation = injectMutation(() => ({
mutationFn: (newTodo: string) =>
lastValueFrom(this.http.post('/api/todos', { title: newTodo })),
onSuccess: () => {
this.queryClient.invalidateQueries({ queryKey: ['todos'] });
}
}));
addTodo(title: string) {
this.mutation.mutate(title);
}
}- Use query options for reusable queries
@Injectable({ providedIn: 'root' })
export class TodoService {
private http = inject(HttpClient);
getTodoOptions = (id: number) => queryOptions({
queryKey: ['todo', id],
queryFn: () => lastValueFrom(this.http.get(`/api/todos/${id}`))
});
}
@Component({})
export class TodoComponent {
private todoService = inject(TodoService);
todo = this.todoService.getTodoOptions(1);
}- Handle loading and error states
query = injectQuery(() => ({
queryKey: ['todos'],
queryFn: () => fetchTodos(),
retry: 3,
staleTime: 1000 * 60 * 5, // 5 minutes
refetchOnWindowFocus: false
}));- Use invalidation for cache updates
mutation = injectMutation(() => ({
mutationFn: createTodo,
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['todos'] });
}
}));- Use optimistic updates
mutation = injectMutation(() => ({
mutationFn: updateTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: ['todos'] });
const previousTodos = queryClient.getQueryData(['todos']);
queryClient.setQueryData(['todos'], (old: Todo[]) => [...old, newTodo]);
return { previousTodos };
},
onError: (err, newTodo, context) => {
queryClient.setQueryData(['todos'], context.previousTodos);
}
}));Discussions Reference Index
GitHub Discussions
Community
Docs Reference Index
Official Documentation
- TanStack Query Angular - Main guide
- Quick Start
- API Reference