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.
-
Import resource function and API
Add
resourceto your existing imports and import the fake API function.// Add resource to existing importsimport {Component, signal, computed, resource, ChangeDetectionStrategy} from '@angular/core';// Import mock API functionimport {loadUser} from './user-api'; -
Create a resource for user data
Add a property in the component class that creates a resource to load user data based on a user ID signal.
-
Add methods to interact with the resource
Add methods to change the user ID and reload the resource.
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(). -
Create computed signals for resource states
Add computed signals to access different states of the resource.
isLoading = computed(() => this.userResource.status() === 'loading');hasError = computed(() => this.userResource.status() === 'error');Resources provide a
status()signal that can be 'loading', 'success', or 'error', avalue()signal for the loaded data, and ahasValue()method that safely checks if data is available. -
Wire up the buttons and display resource states
The template structure is already provided. Now connect everything:
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 information
Excellent! You've now learned how to use the Resource API with signals. Key concepts to remember:
- Resources are reactive: They automatically reload when params change
- Built-in state management: Resources provide
status(),value(), anderror()signals - Automatic cleanup: Resources handle request cancellation and cleanup automatically
- Manual control: You can manually reload or abort requests when needed
In the next lesson, you'll learn how to pass data to components with input signals!