The createAsyncState operator transforms an observable of type T into an observable of AsyncState<T>, encapsulating loading, error, and data states in a standardized structure. This eliminates the need to manage separate variables for loading states, errors, and data, making your codebase more organized and maintainable.
The AsyncState interface structure that the operator returns:
exportinterfaceAsyncState<T, E = HttpErrorResponse> {
status: ResourceStatus; // 'idle' | 'loading' | 'reloading' | 'resolved' | 'error'isLoading: boolean;
error: E | null;
data: T | null;
}
typeResourceStatus = 'idle' | 'loading' | 'reloading' | 'resolved' | 'error';
// For non-HTTP errors, you can override the default:// AsyncState<Product[], Error>
Examples
Example 1: Simple Request
Handle a single API request with loading and error states:
import {createAsyncState} from'ngx-lift';
// ... other imports@Component({
template: `
<ng-container *ngIf="usersState$ | async as usersState">
<cll-spinner *ngIf="usersState.isLoading"></cll-spinner>
<cll-alert *ngIf="usersState.error as error" [error]="error"></cll-alert>
<div class="card-grid" *ngIf="usersState.data as users">
<app-user-card *ngFor="let user of users" [user]="user"></app-user-card>
</div>
</ng-container>
`,
})
exportclassUserCardListComponent {
usersState$ = inject(UserService).getUsers({results: 9}).pipe(createAsyncState());
}
In scenarios where you have initial data (e.g., from route state), you can provide an initial value to avoid showing a loading spinner. This is useful when navigating from a list to a detail page where you already have some data:
When providing initialValue, set status: 'idle' and isLoading: false to prevent the loading spinner from appearing. The data will be updated seamlessly when the API call completes.
(Optional) Callback function or observer object for handling side effects when the observable emits values or errors. Accepts either a partial TapObserver<T> object or a simple function (value: T) => void.
This parameter has the same type signature as RxJS tap operator, allowing you to perform side effects like logging, caching, or triggering other actions.
initialValue
(Optional) The initial AsyncState value to use before the observable emits its first value.
Defaults to { status: 'loading', isLoading: true, error: null, data: null }. Useful when you have pre-existing data (e.g., from route state) and want to avoid showing a loading spinner initially.
Returns
A function that transforms an observable stream into an asynchronous state.
AsyncState Interface
The AsyncState object encapsulates the following properties: