DEV Community

Nhan Nguyen
Nhan Nguyen

Posted on

Angular 19 introduces the experimental Resource API

Angular 19 introduces the experimental Resource API, designed to streamline asynchronous data fetching and state management by integrating with Angular's reactive ecosystem. This API simplifies loading resources, such as data from APIs, by providing a declarative approach that reduces boilerplate code and enhances application consistency.

Key Features of the Resource API:

  1. Declarative Data Fetching: Developers can define resources with minimal code, specifying how data should be fetched and managed. This approach aligns with Angular's reactive principles, making it easier to handle asynchronous operations.

  2. Automatic State Management: The Resource API automatically manages loading states, errors, and data updates, reducing the need for manual state handling in components. This leads to cleaner and more maintainable code.

  3. Reactive Integration: Seamless integration with Angular's Signals and linked signals allows for effortless creation of derived states, such as filtering data based on user input. This enhances applications' responsiveness.

Comparison with Traditional Approaches:

Before Angular 19, developers commonly used HttpClient to fetch data. This method required manual handling of loading indicators, error states, and data transformations, often leading to repetitive code and inconsistencies across the codebase. The Resource API addresses these challenges by encapsulating these concerns within a unified, declarative interface.

Practical Example:

Consider an application that fetches and displays a list of products, allowing users to filter by category. With the Resource API, this can be implemented as follows:

  1. Service Implementation:
import { Injectable, signal, resource } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class ProductService {
  private apiUrl = 'https://dummyjson.com/products';
  private trigger = signal<void>(undefined);

  products = resource({
    request: () => this.trigger,
    loader: async () => {
      const response = await fetch(this.apiUrl);
      if (!response.ok) {
        throw new Error('Failed to fetch products');
      }
      const data = await response.json();
      return data.products;
    },
  });

  reload() {
    this.trigger.set(undefined);
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Component Implementation:
import { Component, signal, linkedSignal } from '@angular/core';
import { ProductService } from '../product.service';

@Component({
  selector: 'app-product-list',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css'],
})
export class ProductListComponent {
  productsResource = this.productService.products;
  selectedCategory = signal<string>('all');

  categories = linkedSignal(() => {
    const products = this.productsResource.value();
    return products ? Array.from(new Set(products.map(product => product.category))) : [];
  });

  filteredProducts = linkedSignal(() => {
    const category = this.selectedCategory();
    const products = this.productsResource.value();
    return category === 'all' ? products : products?.filter(product => product.category === category);
  });

  constructor(private productService: ProductService) {}

  selectCategory(category: string) {
    this.selectedCategory.set(category);
  }

  reload() {
    this.selectedCategory.set('all');
    this.productService.reload();
  }
}
Enter fullscreen mode Exit fullscreen mode

In this setup, the ProductService defines a resource for fetching products, managing the loading state, and handling errors automatically. The component utilizes signals to manage user-selected categories and filters the product list accordingly. This approach reduces boilerplate code and ensures a consistent, reactive data flow within the application.

Conclusion:

The Resource API in Angular 19 represents a significant advancement in handling asynchronous operations within Angular applications. By providing a declarative and reactive approach to data fetching and state management, it enhances code maintainability, reduces redundancy, and aligns with Angular's long-term strategy of signal-based development. As this API is currently experimental, developers are encouraged to explore its capabilities and provide feedback to help shape its future development.


I hope you found it helpful. Thanks for reading. 🙏
Let's get connected! You can find me on:

Top comments (0)