Cover image for Revolutionizing Async Operations with Resource API

Revolutionizing Async Operations with Resource API

Fri Apr 11 2025

Angular 19Resource APISignals

Angular has always been a powerful framework for building web applications, but handling asynchronous operations, especially HTTP requests, has sometimes felt clunky. The upcoming Angular v19, scheduled for release in November 2024, aims to change that with two new experimental APIs: resource and rxResource. These features promise to revolutionize how we handle HTTP requests by providing a more reactive and streamlined approach.

What are Resource and RxResource?

At their core, these new APIs provide a way to handle asynchronous operations with better integration into Angular's signals system:

  • resource: Request an asynchronous operation that returns a Promise and get the result as a writable signal
  • rxResource: Request an asynchronous operation that returns an Observable and get the result as a writable signal

Both APIs are designed to make HTTP requests more reactive and easier to manage within Angular's ecosystem.

Basic Usage of Resource

Let's look at how to use the new resource API for a basic HTTP request:

// Using resource with fetch (Promise-based)
const products = resource({
  loader: async () => {
    const response = await fetch('https://swapi.dev/api/vehicles/');
    return response.json();
  }
});

When this resource is created, it immediately issues the HTTP request. The resource function returns a "resource ref" object, not directly a signal.

RxResource for Observable-based Operations

If you're more familiar with HttpClient and observables, the rxResource API offers a more comfortable approach:

// Inject HttpClient
private http = inject(HttpClient);

// Using rxResource with HttpClient (Observable-based)
const products = rxResource({
  loader: () => this.http.get<ProductResponse>('https://swapi.dev/api/vehicles/')
});

The rxResource automatically handles subscription and unsubscription to the observable. It's important to note that it only considers the first emission, similar to using RxJS's firstValueFrom operator.

Accessing Resource Values and Status

A resource ref has several properties that are signals:

  • value: The result of the async operation
  • status: The current status of the operation
  • error: Any error information

Example of tracking resource status:

effect(() => {
  console.log("Status:", ResourceStatus[products.status()]); 
  console.log("Value:", products.value());
});

The status can be one of the following (from the ResourceStatus enum):

  • loading: The async operation is in progress
  • resolved: The async operation completed successfully
  • error: The async operation failed
  • local: The data has been updated locally

Working with Query Parameters

One of the most powerful features of the new Resource APIs is their reactivity to signal changes, making them perfect for query parameters:

Single Parameter

// Create a signal for the selected product ID
const selectedProductId = signal<number | null>(null);

// Define a resource that reacts to the ID
const product = rxResource({
  request: () => selectedProductId,
  loader: (productId) => this.http.get<Product>(`https://swapi.dev/api/vehicles/${productId}`)
});

Multiple Parameters

// Create signals for multiple parameters
const selectedProductId = signal<number | null>(null);
const color = signal<string | null>(null);

// Define a resource that reacts to both signals
const product = rxResource({
  request: () => ({ id: selectedProductId(), color: color() }),
  loader: (request) => this.http.get<Product>(
    `https://swapi.dev/api/vehicles/${request.id}?color=${request.color}`
  )
});

When any of the signals referenced in the request function change, the resource automatically re-executes the loader function.

Local Updates

Since the resource's value property is a writable signal, you can update it locally:

function onUpdate(): void {
  // Update the product data locally
  product.value.update(currentValue => {
    if (currentValue) {
      return {
        ...currentValue,
        cost_in_credits: '1000000'
      };
    }
    return currentValue;
  });
}

After the update, the status of the resource changes to local, indicating that the data has been modified locally.

Important Considerations

There are some important things to keep in mind when using these new APIs:

  1. Read Operations Only: The documentation explicitly states that resource and rxResource are intended for read operations, not mutations. This is because they can cancel in-progress loads when destroyed or when a new request object becomes available, which could prematurely abort mutations.

  2. Request vs. Loader: Signals defined in the request function are tracked for changes, but those referenced in the loader function are not. Only changes to signals in the request cause the loader to re-execute.

  3. Cancellation: If data is updated while a request is in progress, that request is cancelled, and the update takes precedence.

Conclusion

The new resource and rxResource APIs in Angular v19 provide a powerful way to handle asynchronous operations with better integration into Angular's reactivity system. They allow for:

  • Reactive async code that responds to signal changes
  • Using signals as query parameters
  • Reading HTTP responses as writable signals
  • Tracking request status and errors
  • Cancelling requests when needed
  • Reloading requests automatically

While these features will be experimental in Angular v19, they represent a significant step forward in how Angular handles asynchronous operations. If you're working with Angular, these new APIs are definitely worth exploring when v19 is released in November.

References