RemoteData
and WebData
to use with bs-fetch
and bs-json
for BuckleScript
RemoteData.t
is a simple variant type that allows you to store a data that can have 4 potential states:
Success('a)
: your data has been successfully retrieved and storedFailure('e)
: your data could not be retrievedLoading
: your data is beeing fetchedNotAsked
: you didn't fetch your data yetThis type provides you many usefull functions to handle your data: map
, andThen
, withDefault
, fromOption
, fromResult
, fromPromise
, ...
The main goal for this type is to be used for HTTP requests. That's where WebData
comes into play.
WebData.t
is a RemoteData.t
type but with the error type specified as a WebData.error
. The WebData
module provides some usefull functions to fetch data from API and convert it to a WebData.t
. You can even provide your own Json decoder to convert the result of your API call to a WebData.t
of any type you want/need.
type person = {
age: int,
name: string
};
module Decode = {
let personDecoderExn = json =>
Json.Decode.{
age: json |> field("age", int),
name: json |> field("name", string)
};
let personDecoder = json =>
try (Belt.Result.Ok(personDecoderExn(json))) {
| Json.Decode.DecodeError(err) => Belt.Result.Error(err)
};
};
/* At app launch say you set your data state to `NotAsked` */
let data: WebData.t(person) = RemoteData.NotAsked;
/* You received an event and you need to retrieve your data */
let data: WebData.t(person) = RemoteData.Loading;
Fetch.fetch("http://my-api")
|> WebData.fromResponse(Decode.personDecoder)
|> Js.Promise.then_(data => {
/* Here your data is still a WebData.t(person) and will be
either Success(person), or Failure(httpError) */
});
type person = {
age: int;
name: string;}
module Decode =
struct
let personDecoderExn json =
let open Json.Decode in
{
age = (json |> (field "age" int));
name = (json |> (field "name" string))
}
let personDecoder json =
try ((Belt.Result.Ok ((personDecoderExn json)))[@explicit_arity ])
with
| ((Json.Decode.DecodeError (err))[@explicit_arity ]) ->
((Belt.Result.Error (err))[@explicit_arity ])
end
let data: person WebData.t = RemoteData.NotAsked
let data: person WebData.t = RemoteData.Loading
let _ =
((Fetch.fetch "http://my-api") |>
(WebData.fromResponse Decode.personDecoder))
|> (Js.Promise.then_ (fun data -> object (this) end))
npm install --save bs-remotedata
Then add bs-remotedata
to bs-dependencies
in your bsconfig.json
:
{
...
"bs-dependencies": ["bs-remotedata"]
}
For the moment, please see the interface files: