ngx-remotedata v8.0.0
RemoteData
Slaying a UI Antipattern with Angular.
Library inspired by Kris Jenkins blog post about How Elm slays a UI antipattern, which mixes pretty well with another article written by Scott Hurff about what he calls the UI Stack.

What we are trying to solve
You are making an API request, and you want to display different things based on the status of the request.
The Boolean approach
export interface SunriseSunset {
isInProgress: boolean;
error: string;
data: {
sunrise: string;
sunset: string;
};
}Let’s see what each property means:
isInProgress: It‘s true while the remote data is being fetched.error: It‘s either null (no errors) or any string (there are errors).data: It’s either null (no data) or an object (there is data).
There are a few problems with this approach but the main one is that it is possible to create invalid states such:
{
isInProgress: true,
error: 'Fatal error',
data: {
sunrise: 'I am good data.',
sunset: 'I am good data too!',
}
}Our template will have to use complex *ngIf statements to make sure that we are displaying precisely what we should.
The RemoteData approach
Instead of using a complex object we use a single data type to express all possible request states:
type RemoteData<T, E = string> =
| NotAsked
| InProgress<T>
| Failure<E, T>
| Success<T>;This approach makes it impossible to create invalid states.
Installation
npm install --save ngx-remotedata
Basic Usage
// app.module.ts
import { RemoteDataModule } from 'ngx-remotedata';
@NgModule({
imports: [
// (...)
RemoteDataModule
]
})// app.component.ts
import { InProgress, NotAsked, Success, Failure } from 'ngx-remotedata';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
remoteData: RemoteData<string> = NotAsked.of();
setNotAsked() {
this.remoteData = NotAsked.of();
}
setInProgress() {
this.remoteData = InProgress.of('In progress...');
}
setSuccess() {
this.remoteData = Success.of('Success!');
}
setFailure() {
this.remoteData = Failure.of('Wrong!');
}
}<!-- app.component.html -->
<ul>
<li><button (click)="setNotAsked()">Not Asked</button></li>
<li><button (click)="setInProgress()">InProgress</button></li>
<li><button (click)="setSuccess()">Success</button></li>
<li><button (click)="setFailure()">Failure</button></li>
</ul>
<hr />
<h4 *ngIf="remoteData | isNotAsked">Not Asked</h4>
<h4 *ngIf="remoteData | isInProgress">InProgress...</h4>
<h4 *ngIf="remoteData | isSuccess" style="color: green">
{{ remoteData | successValue }}
</h4>
<h4 *ngIf="remoteData | isFailure" style="color: red">
{{ remoteData | failureValue }}
</h4>Some examples
Api
RemoteData
RemoteData<T, E = string>
RemoteData is used to annotate your request variables. It wraps all possible request states into one single union type. Use the parameters to specify:
T: The success value type.E: The error value type (stringby default).
NotAsked
NotAsked
When a RemoteData is an instance of the NotAsked class, it means that the request hasn't been made yet.
type User = { email: string };
const remoteData: RemoteData<User> = NotAsked.of();InProgress
InProgress<T>
When a RemoteData is an instance of the InProgress class, it means that the request has been made, but it hasn't returned any data yet. The InProgress class can contain a value of the same T type as the Success class. Useful when you want to use the last Success value while the new data is being fetched.
type User = { email: string };
const remoteData: RemoteData<User> = InProgress.of({ email: 'john@doe.com' });Success
Success<T>
When a RemoteData is an instance of the Success class, it means that the request has completed successfully and the new data (of type T) is available.
type User = { email: string };
const remoteData: RemoteData<User> = Success.of({ email: 'john@doe.com' });Failure
Failure<E, T>
When a RemoteData is an instance of the Failure class, it means that the request has failed. You can get the error information (of type E) from the payload and.
As with the InProgress class, Failure can optionally contain a value of the same T type as the Success class. Useful when you want to use the last Success value while displaying the failure message.
type User = { email: string };
const remoteData: RemoteData<User> = Failure.of('Something went wrong.');The default type for errors is string, but you can also provide other types like Error:
type User = { email: string };
const remoteData: RemoteData<User, Error> = Failure.of(
new Error('Something went wrong.')
);Pipes
isNotAsked
isNotAsked | RemoteData<any> : boolean
Returns true when RemoteData is a NotAsked instance.
anyIsNotAsked
anyIsNotAsked | Observable<RemoteData<any>>[] : boolean
Returns true when any RemoteData<any>[] item is a NotAsked instance.
isInProgress
isInProgress | RemoteData<any> : boolean
Returns true when RemoteData is an InProgress instance.
anyIsInProgress
anyIsInProgress | Observable<RemoteData<any>>[] : boolean
Returns true when any RemoteData<any>[] item is an InProgress instance.
isFailure
isFailure | RemoteData<any> : boolean
Returns true when RemoteData is a Failure instance.
isSuccess
isSuccess | RemoteData<any> : boolean
Returns true when RemoteData is a Success instance.
hasValue
hasValue | RemoteData<any> : boolean
Returns true when RemoteData is a Success instance or is an InProgress or Failure instance with a value that is not null or undefined.
successValue
successValue | RemoteData<T> : (T | undefined)
Returns the Success payload (of type T) when RemoteData is a Success instance or undefined otherwise.
inProgressValue
inProgressValue | RemoteData<T> : (T | undefined)
Returns the InProgress payload (of type T) when RemoteData is an InProgress instance or undefined otherwise.
remoteDataValue
remoteDataValue | RemoteData<T> : (T | undefined)
Returns the InProgress, Failure or Success payload (of type T) when RemoteData is an InProgress, Failure or Success instance, returns undefined otherwise.
failureError
failureError | RemoteData<T, E> : (E | undefined)
Returns the Failure error payload (of type E) when RemoteData is a Failure instance or undefined otherwise.
failureValue
failureValue | RemoteData<T, E> : (T | undefined)
Returns the Failure payload (of type T) when RemoteData is a Failure instance or undefined otherwise.
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago