This Is a Test Fragment for Experimental Bite-Sized Content.

High Signal - Low Noise
Compact, meaningful takeaways with zero distractions.


What Does Angular Query Do?

Quick rundown 👇


Angular Query keeps server-side data in sync with the client app layer.

  • No unnecessary layers in between.

Best suited for

  • data grids
  • tables
  • sorted lists
  • and similar patterns

Two packages you should know about

  1. ngneat/query
  2. tanstack/angular-query-experimental

ngneat is a community-driven adapter

TanStack considers theirs the official one

Both share TanStack Query Core under the hood.

🟨 Fundamental Ideas 🟨


1. Queries

  • Take a declarative approach to data fetching.
  • Angular Query decides when and how to talk to the server.

2. Mutations

  • Manage data changes
  • Then tie into queries so all data stays aligned

🧹 Caching and Retention 🧹


1. How Caching Works

  • The Query Client & Query Cache take care of storing and retrieving data.

2. Query Keys

  • Used to label and track data that multiple components may rely on.

3. Stale-While-Revalidate

  • Keeps data current by quietly refreshing it in the background, without hurting performance.

💻 Noticeable improvements for developers 💻

  • Less boilerplate immediately
  • Smart cache and data management built in
  • Speed up async code writing significantly
  • Works well alongside component state libraries

How to start with ngneat/query:

Using it in a service:

kg-card-begin: html

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(
          'https://jsonplaceholder.typicode.com/todos',
        );
      },
    });
  }
}
          

When working at the component level, Observables serve as the data transport mechanism:

kg-card-begin: html

@Component({
  standalone: true,
  template: `
    @if (todos.result$ | async; as result) {
      @if (result.isLoading) {
           Loading
      }
      @if (result.isSuccess) {
         {{ result.data[0].title }}
      }
      @if (result.isError) {
          Error
      }
    }
  `,
})
export class TodosPageComponent {
  todos = inject(TodosService).getTodos();
}
          

Working with Signals inside a component looks like this:


@Component({
  standalone: true,
  template: `
    @if (todos().isLoading) {
        Loading
    }
    @if (todos().data; as data) {
        {{ data[0].title }}
    }
    @if (todos().isError) {
        Error
    }
  `,
})
export class TodosPageComponent {
  todos = inject(TodosService).getTodos().result;
}
          
---

If this brief format works for you, drop me a note with your preference.

Vote or reply via e-mail—encouraged.

  • ngneat/query:
GitHub - ngneat/query: 🚀 Powerful asynchronous state management, server-state utilities and data fetching for Angular Applications
🚀 Powerful asynchronous state management, server-state utilities and data fetching for Angular Applications - GitHub - ngneat/query: 🚀 Powerful asynchronous state management, server-state utilities…
  • TanStack Angular Query:
Overview | TanStack Query Docs
VERY IMPORTANT: This library is currently in an experimental stage. This means that breaking changes will happen in minor AND patch releases. Use at your own risk. If you choose to rely on this in production in an experimental stage, please lock your version to a patch-level version to avoid unexpected breakages. The @tanstack/angular-query-experimental package offers a 1st-class API for using TanStack Query via Angular.

Tagged in:

Bite-Sized

Last Update: February 03, 2024