rxjs-loading-state eliminates manual state management for loading and error states by transforming Observables
into a LoadingState
.
Installation via NPM:
npm install rxjs-loading-state --save
You create a LoadingStateMachine
object and connect it to your observable. This object now reflects the loading state of your Observable:
// Create a new LoadingStateMachine instance
const machine = new LoadingStateMachine<number>();
// Create an Observable that finishes after 1000ms and track it by the machine
const loadData$ = of(42).pipe(delay(1000), trackLoadingBy(machine));
// As long as no one is subscribed, loading state is in "notStarted" state
console.log(machine.state); // "notStarted"
// After subscription, loading state transitions to "loading" state
loadData$.subscribe();
console.log(machine.state); // "loading"
// After 2s the Observable is completed and loadingState transitioned to "success"
setTimeout(() => {
console.log(machine.state); // "success"
}, 2000);
The LoadingStateMachine
is a small state-machine that consists of four states it can be in:
Type | Description |
---|---|
LoadingStateName.NotStarted |
Loading has not been started yet. |
LoadingStateName.Loading |
Data is getting loaded. Could be the first load or a reload. |
LoadingStateName.Error |
An error occurred during loading. |
LoadingStateName.Success |
Data has successfully been loaded. |
Transition between these steps can be performed with event methods. This state-chart gives an overview, which event can be called in which state.
Note: If an event is triggered in an invalid state, the state machine rises an exception!
const machine = new LoadingStateMachine<string>();
machine.start();
console.log(machine.state); // "loading"
console.log(machine.data); // undefined
machine.succeed("my-data");
console.log(machine.state); // "success"
console.log(machine.data); // "my-data"
machine.succeed("boo"); // throws IllegalStateTransitionError: Transition from success to success not allowed
Although you can manually trigger state changes on a LoadingStateMachine
, there is a better way to do it.
The trackLoadingBy
operator connects your state machine to an existing Observable. As soon as a subscription to this Observable starts, the LoadingStateMachine
instance gets updated automatically and can be used in your view template.
const machine = new LoadingStateMachine();
fetchData().pipe(trackLoadingBy(machine)).subscribe();
// later in your render-loop or template
function render() {
if (machine.isLoading()) {
return "loading...";
}
if (machine.isError()) {
return "error: " + machine.error.message;
}
if (machine.isSuccess()) {
return "data fetched: " + machine.data;
}
}
Kind: global class
- LoadingStateMachine
- new LoadingStateMachine()
- instance
- .data
- .error
- .state
- .asObservable() ⇒
Observable<LoadingState>
- .update(newData)
- .start()
- .succeed(data)
- .fail(error)
- .reset()
- .isNotStarted() ⇒
Boolean
- .isLoading() ⇒
Boolean
- .isError() ⇒
Boolean
- .isSuccess() ⇒
Boolean
- static
- .asError(error) ⇒
LoadingStateMachine<T>
- .asSuccess(data) ⇒
LoadingStateMachine<T>
- .asLoading(data) ⇒
LoadingStateMachine<T>
- .asError(error) ⇒
Handles transitions between different loading state and holds the context data that is related to the current state.
Data of the current state. Depending on the current state, this may be undefined.
Kind: instance property of LoadingStateMachine
Error of the current state. Depending on the current state, this may be undefined.
Kind: instance property of LoadingStateMachine
The current LoadingState
Kind: instance property of LoadingStateMachine
Creates a new observable that represents the current state of the machine
Kind: instance method of LoadingStateMachine
Returns: Observable<LoadingState>
- Observable that emits the machine state
Update data while in loading state
Kind: instance method of LoadingStateMachine
Param | Type |
---|---|
newData | T |
Starts loading
Kind: instance method of LoadingStateMachine
Transition to success state
Kind: instance method of LoadingStateMachine
Param | Type |
---|---|
data | T |
Transition to error state
Kind: instance method of LoadingStateMachine
Param | Type |
---|---|
error | any |
Resets machine to not started
Kind: instance method of LoadingStateMachine
Kind: instance method of LoadingStateMachine
Returns: Boolean
- True if machine if loading has not been started or reset
Kind: instance method of LoadingStateMachine
Returns: Boolean
- True if machine is in loading state
Kind: instance method of LoadingStateMachine
Returns: Boolean
- True if machine is in error state
Kind: instance method of LoadingStateMachine
Returns: Boolean
- True if machine is in success state
Factory to create a new machine in error state
Kind: static method of LoadingStateMachine
Returns: LoadingStateMachine<T>
- The new LoadingStateMachine
Param | Type |
---|---|
error | any |
Factory to create a new machine in success state
Kind: static method of LoadingStateMachine
Returns: LoadingStateMachine<T>
- The new LoadingStateMachine
Param | Type |
---|---|
data | T |
Factory to create a new machine in loading state
Kind: static method of LoadingStateMachine
Returns: LoadingStateMachine<T>
- The new LoadingStateMachine
Param | Type |
---|---|
data | T | undefined |
Tracks an observable, by emitting loading events to the passed in state machine
Kind: global function
Param | Type |
---|---|
loadingStateMachine | LoadingStateMachine<Data> |