Skip to content

Instantly share code, notes, and snippets.

@greyblake
Created August 16, 2021 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save greyblake/c8efd274f381ee07a49a738b93960d80 to your computer and use it in GitHub Desktop.
Save greyblake/c8efd274f381ee07a49a738b93960d80 to your computer and use it in GitHub Desktop.
// USAGE EXAMPLE
render() {
const { currentUserState, nearEnv } = this.state;
return currentUserState.match({
notAsked: () => <HomePage />,
loading: () => <HomePage />,
failure: (err) => <>Error occurred</>,
success: (user) => <AppRouter currentUser={user} nearEnv={nearEnv} />,
});
}
// DEFINITION
type RemoteDataInner<T> =
{ type: 'NOT_ASKED' }
| { type: 'LOADING' }
| { type: 'FAILURE', error: Error }
| { type: 'SUCCESS', data: T }
interface MatchHandlers<T, R> {
notAsked: () => R,
loading: () => R,
success: (data: T) => R,
failure: (error: Error) => R,
}
class RemoteData<T> {
inner: RemoteDataInner<T> = { type: 'NOT_ASKED' };
constructor(inner: RemoteDataInner<T>) {
this.inner = inner;
}
public static newNotAsked<T>(): RemoteData<T> {
const inner: RemoteDataInner<T> = { type: 'NOT_ASKED' };
return new RemoteData<T>(inner);
}
static newLoading<T>(): RemoteData<T> {
const inner: RemoteDataInner<T> = { type: 'LOADING' };
return new RemoteData<T>(inner);
}
static newFailure<T>(error: Error): RemoteData<T> {
const inner: RemoteDataInner<T> = { type: 'FAILURE', error };
return new RemoteData<T>(inner);
}
static newSuccess<T>(data: T): RemoteData<T> {
const inner: RemoteDataInner<T> = { type: 'SUCCESS', data };
return new RemoteData<T>(inner);
}
match<R>(handlers: MatchHandlers<T, R>): R {
switch (this.inner.type) {
case 'NOT_ASKED': {
return handlers.notAsked();
}
case 'LOADING': {
return handlers.loading();
}
case 'FAILURE': {
return handlers.failure(this.inner.error);
}
case 'SUCCESS': {
return handlers.success(this.inner.data);
}
default:
throw new Error("match() is supposed to be exhaustive");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment