Skip to content

Instantly share code, notes, and snippets.

@fakenickels
Created July 5, 2020 14:33
Show Gist options
  • Save fakenickels/a5acf18ea27f3db6fea4a430443d7dae to your computer and use it in GitHub Desktop.
Save fakenickels/a5acf18ea27f3db6fea4a430443d7dae to your computer and use it in GitHub Desktop.
module Async = {
type state('a) =
| Idle
| Loading
| Data('a)
| Error(AddpayApi.Api.requestError);
type action('a) =
| Fetch(
Promise.rejectable(
Belt_Result.t('a, AddpayApi.Api.requestError),
Promise.never,
),
)
| SetData('a)
| SetError(AddpayApi.Api.requestError);
/**
Usage:
let session = AppStateSession.useSession();
let (card, cardsSend) = Async.use(() => {
Api.CardGet(~input={}, session)
})
*/
let use = fn => {
let (state, send) =
ReactUpdate.useReducer(Idle, (action, _state) => {
switch (action) {
| Fetch(promise) =>
UpdateWithSideEffects(
Loading,
self => {
let () =
promise->Promise.get(result => {
switch (result) {
| Ok(data) => self.send(SetData(data))
| Error(msg) => self.send(SetError(msg))
}
});
None;
},
)
| SetData(data) => Update(Data(data))
| SetError(data) => Update(Error(data))
}
});
let fetchWithArgs =
fn(~cb=request => {
let promise = request();
// dispatch promise instance for declarative usage
send(Fetch(promise));
// send same promise instance for local instance handling
promise;
});
(state, fetchWithArgs);
};
let getData = (state, fn) => {
switch (state) {
| Data(data) => fn(data)
| _ => ()
};
};
let isData =
fun
| Data(_) => true
| _ => false;
let isLoading =
fun
| Loading => true
| _ => false;
let isError =
fun
| Error(_) => true
| _ => false;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment