The Vision Behind It: Loading Async Data With Signals
The concept for these APIs stems from a pull request submitted by Alex Rickabaugh. At its heart, the idea is to use Signals as the mechanism for handling asynchronous resource loading. The resource API works with Promises, while rxResource is built around Observables, giving developers the option to pick whichever paradigm they're more comfortable with. Both return a WritableResource instance, which makes it possible to modify the resource's data directly on the client side.
A resource exposes a set of signals that reflect its current state:
- Value: Holds the actual data returned by the resource, representing the outcome of the query.
- Status: Indicates the current phase of the resource. The possible statuses are listed below:
- Error: Supplies information about any issues that came up while retrieving data.
Setting Up a Resource
Creating a resource is straightforward:
This leads to the output shown below. Observe that the status starts out as "Loading" (2) and eventually transitions to "Resolved" (4).
Modifying Resource Data on the Client
If you need to change the resource's data without making another server call, the update() method on the value signal is what you want. The template and component below demonstrate the pattern:
The updateResource() method swaps the current resource value for a different string locally.
Here's what you'll see after that runs. Pay attention to the status reading "Local" (5), signaling a client-side update.
Triggering a Resource Refresh
Let's add a Refresh button to the template so the user can manually re-fetch the data.
The reload function in the example below tells the resource loader to run once more. If the user clicks Refresh multiple times in a row, the loader won't fire again until the ongoing request completes. This behavior mirrors how exhaustMap works in Rxjs.
In the output that follows, you can observe the status shifting from "Reloading" (3) to "Resolved" (4).
Signal-Driven Data: Loading Resources Dynamically
Imagine you want to pull posts based on an postId signal. You can pass that signal straight into the endpoint as a request parameter:
Using postId as a request parameter lets you retrieve data dynamically, driven by whatever value that signal currently holds. A quick demo:
The output looks like this:
That setup works fine for the first fetch, but it's not reactive. Loaders in Angular's resource API run untracked by default. So if postId changes after the resource is first created, the loader won't kick in again on its own.
To make things truly reactive, you have to explicitly link the signal to the resource's request parameter. That connection forms a dependency between the resource and the signal, so any change to the signal's value automatically re-triggers the loader.
Let's wire up a button that sets postId to a random number.
Inside the component, we add a method that assigns a random number to the postId signal. We also bind postId to the request parameter of the resource to keep the reactivity intact.
Dealing with Local Updates While Requests Are In Flight
If you make a local change while the resource is still waiting on a remote call, you can run into a race condition. The abortSignal() function helps us handle that gracefully.
By handing an AbortSignal to the resource's loader, we can stop a request that's already underway if that signal gets aborted. This becomes especially handy when a new request fires off before the previous one has wrapped up.
Here's how the flow works:
- Local change applied: The user tweaks the data locally, which sets off a new request.
- Abort signal created: An AbortSignal is generated and passed along to the resource's loader.
- Pending request canceled: If an earlier request is still active, it gets canceled using the AbortSignal.
- Fresh request launched: The loader fires again with the updated
postIdand the new AbortSignal. - Data retrieved and applied: The new request completes, and the resource's value gets overwritten with the latest data.
The example below fetches data based on the newest value of the signal and cancels any request that's still running if multiple triggers occur.
Watching Multiple Signals for Reactive Loading
A resource can stay in sync with changes across multiple signals, enabling richer data-fetching scenarios. Bind several signals to the request parameter, and the loader will re-run whenever any of those signals shifts.
In the example below, both postId and userId get assigned random numbers, and the resource is set up to react when either one changes:
When either userId or postId changes, the loader is invoked again. This guarantees that the resource always mirrors the latest state of its dependent signals.
Building Reusable Resource Functions
For cleaner, more maintainable code, you can define resource functions that are reusable across your app. These functions wrap the logic needed to create resources with particular settings, making them easy to share.
Here's one such reusable function:
In that snippet, myResource can be reused across various parts of the application, promoting cleaner code and better reusability.
RxResource: Harnessing Observables for Asynchronous Data Handling
For applications that already embrace Observables, the rxResource API offers a robust solution for managing asynchronous data workflows. It mirrors the resource API's functionality but emits data through an Observable stream.
What Sets rxResource Apart from resource
- Observable-Driven: Instead of raw values,
rxResourcerelies onObservablesto deliver a continuous data stream, enabling richer reactive patterns. - No abortSignal Required: Because subscriptions to
Observablescan be cleanly terminated, the explicitabortSignalis unnecessary. - Single-Emission Focus: In its current form, rxResource processes only the first value emitted by the Observable; any subsequent values are disregarded.
- Mutable Local State: Similar to resource,
rxResourcesupports modifying local resource state viaObservables.
The snippet below demonstrates how to build a resource with rxResource:
Here, the loader function produces the posts as an Observable. Subscribing to this stream allows you to respond to changes and trigger side effects as needed.
Final Thoughts
The introduction of resource and rxResource APIs in Angular marks a notable advancement in handling asynchronous operations. They bring a more declarative and streamlined method to data fetching, which contributes to better developer experience and application responsiveness.
Even though these APIs are in developer preview, they have the potential to transform data management strategies in Angular. By capitalizing on Signals and Observables, they deliver a versatile and performant pathway for managing reactivity and data flow.
Github PR: https://github.com/angular/angular/pull/58255
Code repository: https://github.com/Ingila185/angular-resource-demo
Stackblitz Playground: https://stackblitz.com/edit/stackblitz-starters-hamcfa?file=src%2Fmain.ts
Special thanks to Enea Jahollari for the comprehensive write-up on resource and rxResource for Push Based.

















