https://github.com/bloodyowl/rescript-asyncdata
A ReScript variant type to represent async data
https://github.com/bloodyowl/rescript-asyncdata
Last synced: 10 months ago
JSON representation
A ReScript variant type to represent async data
- Host: GitHub
- URL: https://github.com/bloodyowl/rescript-asyncdata
- Owner: bloodyowl
- License: mit
- Created: 2020-11-03T08:17:09.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2021-06-17T07:05:56.000Z (over 4 years ago)
- Last Synced: 2025-01-25T12:27:39.368Z (12 months ago)
- Language: ReScript
- Size: 213 KB
- Stars: 26
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: HISTORY.md
- License: MIT-LICENSE
Awesome Lists containing this project
- awesome-list - rescript-asyncdata
README
# AsyncData
> A ReScript variant type to represent async data
## Installation
Run the following in your console:
```console
$ yarn add rescript-asyncdata
```
Then add `rescript-asyncdata` to your `bsconfig.json`'s `bs-dependencies`:
```diff
{
"bs-dependencies": [
+ "rescript-asyncdata"
]
}
```
## Basics
**AsyncData** provides a variant type that helps you represent the state of an async request. The type consists of three tags:
- `NotAsked`: the request hasn't started yet
- `Loading`: the request has been initialised and we're waiting for a response
- `Done('a)`: the request has finished with `'a`
## Representing success & failure states
ReScript provides a `result<'ok, 'error>` type to represent an operation success.
You can combine `AsyncData.t` and `result` to represent a possible request failure state:
```reason
type userFromServer = AsyncData.t>
```
> Note that you can use your own error type in place of `exn`
Then, you can pattern match:
```reason
switch userFromServer {
| NotAsked => React.null
| Loading =>
| Done(Error(error)) =>
| Done(Ok(user)) =>
}
```
## Representing reload
You can combine multiple `AsyncData.t` to represent more complex loading styles:
```reason
type reloadableUserFromServer = {
userFromServer: userFromServer,
userFromServerReload: userFromServer,
}
let initialState = {
userFromServer: NotAsked,
userFromServerReload: NotAsked
}
let firstLoad = {
userFromServer: Loading,
userFromServerReload: NotAsked
}
let firstLoadDone = {
userFromServer: Done(Ok(user)),
userFromServerReload: NotAsked
}
let reload = {
userFromServer: Done(Ok(user)),
userFromServerReload: Loading
}
// If you just want to replace the previous state
let reloadDone = {
userFromServer: Done(Ok(newUser)),
userFromServerReload: NotAsked
}
// If you want to compare/show a diff
let reloadDone = {
userFromServer: Done(Ok(user)),
userFromServerReload: Done(Ok(newUser))
}
```
## Utility functions
This package contains a few utility functions to manipulate `AsyncData.t`:
- `getExn`: Extract the `Done('a)` payload or throw
- `getWithDefault`: Extract the `Done('a)` payload or return a default value
- `mapWithDefault`: Extract and map the `Done('a)` payload or return a default value
- `map`: Map the `Done('a)` payload
- `flatMap`: Map the `Done('a)` payload with a callback that returns a `AsyncData.t`
- `isLoading`
- `isNotAsked`
- `isDone`
- `cmp`: For sorting
- `eq`: For comparison
## Aknowledgments
This is heavily inspired by Elm's [krisajenkins/remotedata](https://github.com/krisajenkins/remotedata)