🚀 The Ultimate Angular Adapter for TanStack Query
🚀🌟 Big News for Angular Developers! 🌟🚀
I’m thrilled to unveil the next big leap in Angular development — the latest release of ngneat/query! This isn’t just any update; it’s a game-changer for everyone using Angular with the TanStack Query (also known as react-query).
Get rid of granular state management, manual refetching, and async spaghetti code. TanStack Query gives you declarative, always-up-to-date auto-managed queries and mutations that improve your developer experience.
The Angular adapter features: Observable & Signal Support, Backend Agnostic architecture, Dedicated Devtools, Auto Caching, and Auto Refetching. It also includes advanced functionalities like Polling/Realtime Queries, Parallel and Dependent Queries, Mutations API, and Automatic Garbage Collection. Enhanced user experience is provided through Paginated/Cursor Queries, Load-More/Infinite Scroll Queries, and Offline Support, along with crucial technical capabilities like Request Cancellation, Prefetching, and SSR Support.
We have been utilizing the adapter in our production environment for over a year now, and it has proven to be a significant time-saver, streamlining our workflow remarkably.
Install the library via npm:
npm i @ngneat/query
Create a service and use the injectQuery
function:
import { injectQuery, toPromise } from '@ngneat/query';
@Injectable({ providedIn: 'root' })
export class TodosService {
#http = inject(HttpClient);
#query = injectQuery();
getTodos() {
return this.#query({
queryKey: ['todos'] as const,
queryFn: ({ signal }) => {
const source = this.http.get<Todo[]>(
'https://jsonplaceholder.typicode.com/todos'
);
return toPromise({ source, signal });
},
});
}
}
Utilize the toPromise
helper function to transform the observable into a promise. You can also optionally pass a signal
parameter if you need cancellation behavior.
🔥 New Signal Support
To stay in step with Angular’s evolving landscape, we now offer a signal
through the result
property:
@Component({
standalone: true,
template: `
@if (todos(); 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().result
}
🚀 Enhanced RxJS Support
For those who love reactive programming, RxJS support means more power, flexibility, and efficiency in handling data streams and complex async operations. Get ready to transform your coding with our new operators.
To get an observable use the result$
property:
@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();
}
🤓 Intersection API
The intersectResults
function combines multiple signal queries into a single unified base query result. This function merges the outcomes of all queries, ensuring that data is mapped only if the result is successful:
import { intersectResults } from '@ngneat/query';
@Component({
standalone: true,
template: `
@if (intersection(); as intersectionResult) {
@if (intersectionResult.isLoading) {
<p>Loading</p>
}
@if (intersectionResult.isSuccess) {
<p>{{ intersectionResult.data }}</p>
}
@if (intersectionResult.isError) {
<p>Error</p>
}
}
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TodosPageComponent {
#todosService = inject(TodosService);
intersection = intersectResults(
[
this.#todosService.getTodo('1').result,
this.#todosService.getTodo('2').result,
],
([todoOne, todoTwo]) => todoOne.title + todoTwo.title
);
}
We also offer an operator variant specifically designed for RxJS integration.
⭐️ There is More
And that’s not all! There are numerous other improvements, enhancements, and tweaks that we’ve added to make ngneat/query
the best version it can be. We’re committed to providing Angular developers with the tools and resources they need to succeed. 🌈
Follow me on Medium or Twitter to read more about Angular and JS!