In v19, Angular will introduce a new API for loading resources. This would allow us to fetch data from an api, know about the status of the request, and update the data locally when needed.
The resource API is very simple in it's core. Let's see the most simple example of how to use it.
The first thing we can notice is that the resource API uses Promises by default for the loader parameter. The other one is that the resource API will return a WritableResource object, which helps us to update the data locally when needed.
We can read the current value of the resource by using the value signal, the status of the resource by using the status
signal, and the error of the resource by using the error signal.
The code above will print the following:
Let's see how we can update the data locally.
We can update the data locally by using the update method of the value signal.
This will print the following:
The 'local' status means that the data was updated locally.
Let's make a proper request to the server. Let's load some todos from the JSONPlaceholder API.
This todosResource will start to make the request to the server immediately after it has been created.
Of course, the todosResource will not have a value yet, because the request is still in progress.
The code above will print the following:
Refreshing the data Let's say we want to refresh the data when the user clicks on a button.
The refresh function will run the loader function again. If you call the refresh function multiple times, the loader function will be called only once until the previous request is finished (like exhaustMap behavior in RxJS).
Let's say we want to load the todos based on a todoId signal.
This will work fine, but one this to notice is that loader is untracked and that means, that if the todoId signal changes, the load won't be called again. Let's make it more reactive!
Separate the request and the loader We want our resource to refresh the data (call the loader again) every time the todoId changes. For this we can use the request field of the resource. We can pass a signal to it, and it will be tracked.
Now, when the todoId signal changes, the resource API will automatically fetch the new data.
What if we have previous unfinished requests? Let's say we want to cancel the previous request when the todoId changes. Well, we can do that by using the abortSignal that is passed to the loader function.
This will cancel the previous request when the todoId changes and if the previous request is still in progress.
We can also have multiple request dependencies, for example:
Now, the todosResource will make the request based on the limit and query signals, and the loader function will be able to use those signals to make the request, and anytime the limit or query signal changes, the loader function will be called again.
If that's the case, the resource API will automatically update the data locally, but cancel the ongoing request.
Create more reusable resources By separating reactive values from the loader function, we can move the logic of the loader function to a separate function, and store it where we want.
Before:
After:
The todoLoader can be moved anywhere, and also can be reused by other resources. The ResourceLoaderParams type is a type that contains all the information that is needed to make the request, and the request parameter is the one that is passed to the loader function.
Angular has always been about using Observables when it comes to data loading. This means, that we can use Observables to derive the data loading instead of using signals & promises.
In order to make this possible, we can use the rxResource function.
This will make the request based on the limit signal, and the loader function will be able to use the limit value to make the request, and same as signals, anytime the limit signal changes, the loader function will be called again and cancel the previous request (same as switchMap behavior in RxJs)
And same as we can change local state with the signals, we can also change the local state with the observables implementation in the rxResource function.
We have 2 new primitives [resource, rxResource] that will help us make our life easier when dealing with data loading in Angular. These primitives have been requested for so long now, and will land in v19 as developer previews.
PR link: https://github.com/angular/angular/pull/58255