adev/src/content/tutorials/signals/steps/4-managing-async-data-with-signals/README.md
Now that you've learned how to derive state with linked signals, let's explore how to handle asynchronous data with the Resource API. The Resource API provides a powerful way to manage async operations using signals, with built-in loading states, error handling, and request management.
In this activity, you'll learn how to use the resource() function to load data asynchronously and how to handle different states of async operations by building a user profile loader that demonstrates the Resource API in action.
// Add resource to existing imports
import {Component, signal, computed, resource, ChangeDetectionStrategy} from '@angular/core';
// Import mock API function
import {getUserData} from './user-api';
userId = signal(1);
userResource = resource({
params: () => ({id: this.userId()}),
loader: (params) => getUserData(params.params.id),
});
loadUser(id: number) {
this.userId.set(id);
}
reloadUser() {
this.userResource.reload();
}
Changing the params signal automatically triggers a reload, or you can manually reload with reload().
</docs-step>
isLoading = computed(() => this.userResource.status() === 'loading');
hasError = computed(() => this.userResource.status() === 'error');
Resources provide a status() signal that can be 'loading', 'success', or 'error', a value() signal for the loaded data, and a hasValue() method that safely checks if data is available.
</docs-step>
Part 1. Add click handlers to the buttons:
<button (click)="loadUser(1)">Load User 1</button>
<button (click)="loadUser(2)">Load User 2</button>
<button (click)="loadUser(999)">Load Invalid User</button>
<button (click)="reloadUser()">Reload</button>
Part 2. Replace the placeholder with resource state handling:
@if (isLoading()) {
<p>Loading user...</p>
} @else if (hasError()) {
<p class="error">Error: {{ userResource.error()?.message }}</p>
} @else if (userResource.hasValue()) {
<div class="user-info">
<h3>{{ userResource.value().name }}</h3>
<p>{{ userResource.value().email }}</p>
</div>
}
The resource provides different methods to check its state:
isLoading() - true when fetching datahasError() - true when an error occurreduserResource.hasValue() - true when data is availableuserResource.value() - access the loaded datauserResource.error() - access error informationExcellent! You've now learned how to use the Resource API with signals. Key concepts to remember:
status(), value(), and error() signalsIn the next lesson, you'll learn how to pass data to components with input signals!