Angular 19 introduced the Resource API, and with the latest updates, we now have rxResource, a powerful way to handle data fetching in Angular applications. If youβve been working with RxJS-based data streams, signals, and API calls, this blog will show you how rxResource
simplifies your code while improving efficiency.
πΉ What is rxResource?
rxResource
is part of the Angular Core RxJS Interop package, which allows developers to fetch and manage API data in a more reactive, declarative, and efficient way. It:
β
Integrates seamlessly with signals
β
Automatically tracks state (loading, success, error)
β
Works with RxJS streams and Angular's HttpClient
β
Reduces the need for manual subscriptions
πΉ Setting Up rxResource in an Angular App
Project Structure
Here's a glimpse of our Angular project using rxResource
:
angular-examples/
βββ src/
β βββ app/
β β βββ app.component.ts
β β βββ app.component.html
β β βββ app.component.css
β β βββ app.config.ts
β β βββ app.routes.ts
βββ package.json
βββ angular.json
βββ tsconfig.json
βββ README.md
πΉ Implementing rxResource for API Calls
Letβs create a simple comment-fetching app using rxResource
to retrieve data dynamically from an API.
1οΈβ£ Define the Component with rxResource
import { HttpClient } from '@angular/common/http';
import { Component, computed, inject, signal } from '@angular/core';
import { rxResource } from '@angular/core/rxjs-interop';
interface Comment {
postId: number;
id: number;
name: string;
email: string;
body: string;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent {
title = 'angular-examples';
// Signal to track the current Post ID
postId = signal(1);
// Inject HttpClient for API requests
http = inject(HttpClient);
// Fetch comments using rxResource
comments = rxResource({
request: this.postId,
loader: (request) =>
this.http.get<Comment[]>(
`https://jsonplaceholder.typicode.com/comments?postId=${request.request}`
),
});
// Update the Post ID dynamically
updatePostId(event: any) {
const newValue = parseInt(event.target.value, 10);
if (!isNaN(newValue) && newValue > 0) {
this.postId.set(newValue);
}
}
// Navigate between posts
nextPost() {
this.postId.update((current) => current + 1);
}
previousPost() {
if (this.postId() > 1) {
this.postId.update((current) => current - 1);
}
}
// Compute the email of the first comment
firstCommentEmail = computed(() => {
return this.comments.value()?.[0]?.email ?? 'No comments available';
});
}
πΉ Handling UI State with rxResource
The Resource API automatically manages loading, success, and error states. Hereβs how we display them in our UI using Angular's control flow syntax (@if
, @for
):
<div class="container">
<div class="input-container">
<label for="postIdInput" class="input-label">Post ID:</label>
<input type="number" id="postIdInput" [value]="postId()" (input)="updatePostId($event)" class="post-id-input" />
</div>
@if (comments.isLoading()) {
<p class="loading-message">Loading comments...</p>
} @else if (comments.error()) {
<p class="error-message">Error: {{ comments.error() }}</p>
} @else if (comments.hasValue()) {
<p class="total-comments">Total Comments: {{ comments.value().length }}</p>
<ul class="comment-list">
@for (comment of comments.value(); track comment.id) {
<li class="comment-item">
<strong>{{ comment.name }}</strong> ({{ comment.email }}):<br />
<span>{{ comment.body }}</span>
</li>
}
</ul>
<button (click)="comments.reload()" class="refresh-button">Refresh</button>
}
<div class="navigation-container">
<button (click)="previousPost()" [disabled]="postId() <= 1" class="nav-button">Previous Post</button>
<button (click)="nextPost()" class="nav-button">Next Post</button>
<p class="current-post">Current Post ID: {{ postId() }}</p>
</div>
<div class="first-email-container">
<p>First comment email: {{ firstCommentEmail() }}</p>
</div>
</div>
πΉ Benefits of Using rxResource
β Automatic State Handling
-
rxResource
automatically tracks loading, success, and error states, removing the need for manual handling.
β Better Performance
- It caches API responses and minimizes redundant requests, reducing network calls.
β Cleaner Code
- No need to manually handle RxJS subscriptions, reducing complexity.
β Seamless Integration with Signals
- Works perfectly with Angular signals, making reactivity easier.
πΉ Configuring HttpClient for rxResource
Since rxResource
relies on HttpClient, we need to provide it in the app.config.ts file:
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter([]),
provideHttpClient(), // Ensure HttpClient is available
],
};
πΉ Running the Project
To try out rxResource
in AngularExamples, follow these steps:
1οΈβ£ Clone the Repository:
git clone https://github.com/manthanank/angular-examples.git
cd angular-examples
2οΈβ£ Checkout to rxresource Branch:
git checkout rxresource
3οΈβ£ Install Dependencies:
npm install
4οΈβ£ Run the Development Server:
ng serve
Now, open your browser and go to http://localhost:4200/
. π
πΉ Conclusion
The rxResource API is a game-changer for data fetching in Angular applications. It reduces boilerplate code, improves performance, and integrates seamlessly with signals and RxJS streams.
Exploring the Code
Visit the GitHub repository to explore the code in detail.
Live Demo
Check out the working example on StackBlitz
Additional Resources
Feel free to leave comments or questions below! π
Top comments (0)