Since version 16, Angular has been all about signals. I’ve covered how to create Signals from Observables to transition away from RxJs, but the Angular team introduced an even better option with Angular 19: The resource API.

This API is experimental for now, as shown in the official documentation. This means it’s not recommended for production yet, but it’s such an exciting development that I had to write a tutorial on that topic anyway:

Observables are used in many places in Angular, especially the HttpClient. Using Signals around these Observables, while doable, isn’t always obvious and brings a few extra challenges, such as dealing with default values or undefined.

That’s because Observables are usually asynchronous, and Signals are not. Signals always have a value, while Observables might get one, but later.

The main goal of the resource API is to hide our Observables as much as possible and manage everything around them using Signals.

This includes Signals that give us the current value of a resource, whether it is loading or not, whether it throws an error, etc.

Here are what these 5 signals are:

As a result, we can use a resource in our component template as follows:

@if (resource.isLoading()) {
ZZ5H
}

@for( passenger of resource.value(); track passenger) {

{{passenger.name}} - {{passenger.trips}} flights


}

No more async pipe, RxJs subscription, operators, none of that. The best part is that creating such a resource is as easy as calling a function and passing our Observable (HttpClient request) as a parameter:

resource = rxResource({
loader: () =>
this.http.get("https://api.instantwebto.com")
});

Note that I use the rxResource function because I’m using an Observable here with the HttpClient. There is also a resource function for those using Promises and fetch.

That’s probably the best part of the API. We can define multiple different parameters using Signals, and the resource will automatically trigger new requests when these parameters change.

For instance, let’s say I want to use a paginator like this:

Whenever the page size changes or the user clicks on the “Previous” or “Next” page buttons, I want to send a request to my server with updated page information.

We can capture all these params using signals and aggregate them into a single computed signal:

  readonly page = signal(0);
readonly pageSize = signal(10);

readonly pageConfig = computed(() => ({
page: this.page(),
pageSize: this.pageSize(),
}));

Then we pass that computed signal as a parameter to the resource:

 readonly resource = rxResource({
request: () => this.pageConfig(),
loader: (params) =>
this.http.get(
`https://api.com?page=${params.request.page}
&size=${params.request.pageSize}`
)
})

Now, when the user clicks on any of the pagination buttons, all we do is update our “trigger” signals:

 nextPage() {
this.page.update((page) => page + 1);
}

And that’s it! Updating the page signal will automatically update the pageConfig signal, trigger a new request with those updated parameters, set the loading state to true, and then display the new value (page) when available!

No Subjects, switchMap operators, or complex state management operations.

If we want to fetch updated data from a server using a resource programmatically, all we have to do is:

resource.reload()

Also, a resource will automatically abort HTTP requests (Observables) if the request triggers change again before the HTTP request completes.

In my example, if the user clicks quickly on the “Next page” button multiple times, all “intermediate page” requests will get canceled automatically, and only the final request will complete:

The API does so much work for us that I couldn’t ignore it, despite its current experimental state.

You can see the code example of this post in action here on Stackblitz.

My name is Alain Chautard. I am a Google Developer Expert in Angular and a consultant and trainer at Angular Training, where I help web development teams learn and become comfortable with Angular.

If you need any help with web development, feel free to get in touch!

If you enjoyed this article, please clap for it or share it. Your help is always appreciated. You can also subscribe to my articles and my Daily Angular Newsletter to receive helpful daily tips.

Share.
Leave A Reply