![Signals + HTTP = httpResource [Tutorial]](https://api.certificates.dev/storage/BjlMXbKIMa9oxIOAYDExd172ChCzAax9YCFpoWbl.png)
Angular 19.2 rolls out httpResource — an experimental, signal-friendly layer over HttpClient that lets you fetch data reactively. Instead of juggling Observables and state flags, httpResource gives you built-in signals like isLoading() and hasValue(), and it automatically re-fires requests when dependent signals (e.g. page number, query) change.
Alain Chautard
September 25, 2025
Angular 19.2 brought an experimental new API called httpResource. I published a tutorial about rxResource a few months ago, and httpResource is a new, more polished layer on top of that.
Let’s start with the basics. Signals are slowly making their way across all APIs of the Angular framework, which begs the question: How do we use the Angular HttpClient with Signals, since the HttpClient returns an Observable?
A simple answer would be to use the toSignal function:
signal = toSignal(this.http.get("http://mydata.com"));
While the above works, it doesn’t help us know:

The resource API fixes that because it returns a bunch of Signals and methods that answer all these questions:

We can check resource.hasValue() or resource.isLoading() to get our answers.
Creating a resource for HTTP requests is as easy as it gets:
resource = httpResource('https://dummyjson.com/users');
Of course, we can add type information using TypeScript to specify the kind of data we expect from the server:
resource = httpResource<UserList>('https://dummyjson.com/users');
Now, if I want to display the data coming from our server through that request, all I need to do is:
@for(user of resource.value(); track user.id) {
<div class="user">
{{user.firstName}} {{user.lastName}} - {{user.age}} years old
</div>
}
And if I want to display a loader/spinner while data is being loaded, I can add:
@if (resource.isLoading()) {
<img src="https://i.gifer.com/ZZ5H.webp" width="50px" />
}
You can see this entire example on Stackblitz here.

Yes, and the beauty of it is that it’s all signal-based. For instance, if we need to support pagination, and that pagination info is used as URL query params like so:
// Get 10 users skipping the first 20
https://dummyjson.com/users?limit=10&skip=20
We can change our resource to accommodate such dynamic URL parameters. The key is to pass a function as a parameter instead of just the URL:
resource = httpResource<UserList>(() => ({
url: `https://json.com/users?limit=${this.pageSize()}&skip=${this.pageSize() * this.page()}`
})
);
In the above example, pageSize() and page() are both signals that have their values bound to a form so the user can change these values by clicking on buttons or interacting with a dropdown:

The HTML template code for that feature is pretty straightforward:
<div class="controls">
Page size
<select [(ngModel)]="pageSize">
<option>5</option>
<option>10</option>
<option>20</option>
</select>
-
<button (click)="previousPage()">< Previous</button>
Page {{page() + 1}} of {{totalPages()}}
<button (click)="nextPage()">Next ></button>
</div>
The magic of all this is that when the user clicks on the next page button, all we do is update a Signal value:
nextPage() {
this.page.update((page) => page + 1);
}
And because page() is a dependency of our httpResource, every change in that value triggers a new HTTP request to fetch updated data, just like with a computed signal.
Join Medium for free to get updates from this writer.
Subscribe
You can see my pagination example in action here on Stackblitz.
You can do that. Of course, it works with all kinds of HTTP requests:
resource = httpResource<UserList>(() => ({
url: `https://json.com/users?limit=${this.pageSize()}&skip=${this.pageSize() * this.page()}`,
method: "POST"
})
);
Just use Signals! Any change in the values of any of these signals would trigger a new request:
resource = httpResource<UserList>(() => ({
url: "api/schools/collection/filter",
method: "POST",
body: {pageSize: this.pageSize(), page: this.page()}
}));
You can apply the same idea to headers, params, URL, etc. Here are all the available options on the **HttpResourceRequest** object, which is the one passed to the httpResource function:
Press enter or click to view image in full size

Note that you can also initiate a manual reload of a resource, and that resources automatically abort the last HTTP request if your code triggers a new request before the previous one completes.
The httpResource API is still experimental, but it will most likely replace all our usages of HttpClient in the near future, which is why I’m excited to share this now!
Get the latest news and updates on developer certifications. Content is updated regularly, so please make sure to bookmark this page or sign up to get the latest content directly in your inbox.

Inside the JavaScript Event Loop: How the Runtime Actually Works
Understand the JavaScript event loop in depth. Learn how the call stack, microtasks, and macrotasks work together to handle asynchronous code efficiently, keeping your applications fast, predictable, and responsive.
Martin Ferret
Nov 18, 2025

React Free Weekend: 48 hours of Open Access to Premium React Certification Training
Every year, we at Certificates.dev look for ways to make our certifications more accessible - not just for teams inside big tech companies, but for every developer who wants to validate their skills through real-world, hands-on learning. That’s why we are excited to announce our first-ever React Free Weekend, taking place on November 15–16, 2025.
Aurora Scharff
Nov 11, 2025

Error Handling in React with react-error-boundary
Learn how to handle errors in React applications with react-error-boundary. Explore fallback UIs, async error handling with useErrorBoundary, and React 19's automatic error boundary integration with form actions and useTransition.
Aurora Scharff
Nov 10, 2025
We can help you recruit Certified Developers for your organization or project. The team has helped many customers employ suitable resources from a pool of 100s of qualified Developers.
Let us help you get the resources you need.
