Skip to content

Instantly share code, notes, and snippets.

@ccapndave
Created June 6, 2018 20:21
Show Gist options
  • Save ccapndave/62bd27b49c79167459e0c8456df7c749 to your computer and use it in GitHub Desktop.
Save ccapndave/62bd27b49c79167459e0c8456df7c749 to your computer and use it in GitHub Desktop.
type state = {coins: Belt.Map.String.t(Coin.t)};
type action =
| CoinsLoad
| CoinsLoadSuccess(Belt.Map.String.t(Coin.t))
| CoinsLoadError(string);
let decodeCoins = json =>
json
|> Json.Decode.dict(Coin.Decode.coin)
|> Js.Dict.entries
|> Belt.Map.String.fromArray;
let fetchCoins = () =>
Js.Promise.(
Fetch.fetch("https://blockchain.info/ticker")
|> then_(Fetch.Response.json)
|> then_(json =>
json |> decodeCoins |> (price => Belt.Result.Ok(price) |> resolve)
)
|> catch(err =>
Belt.Result.Error("dunno how to turn Js.Promise.error into a string")
|> resolve
)
);
let component = ReasonReact.reducerComponent("App");
let make = _children => {
...component,
initialState: () => {coins: Belt.Map.String.empty},
reducer: (action, state: state) =>
switch (action) {
| CoinsLoad =>
ReasonReact.SideEffects(
(
self =>
Js.Promise.(
fetchCoins()
|> then_(result =>
switch (result) {
| Belt.Result.Ok(coins) =>
self.send(CoinsLoadSuccess(coins)) |> resolve
| Belt.Result.Error(err) =>
self.send(CoinsLoadError(err)) |> resolve
}
)
|> ignore
)
),
)
| CoinsLoadSuccess(coins) => ReasonReact.Update({...state, coins})
| CoinsLoadError(err) => ReasonReact.NoUpdate
},
render: self => {
let tickers =
self.state.coins
|. Belt.Map.String.mapWithKey((key, coin) =>
<Ticker coin coinName=key />
)
|. Belt.Map.String.valuesToArray;
<div>
<button onClick=(_event => self.send(CoinsLoad))>
(ReasonReact.string("Load price"))
</button>
<div className="tickers"> (ReasonReact.array(tickers)) </div>
</div>;
},
};
type t = {
buy: float,
sell: float,
symbol: string,
};
module Decode = {
let coin = json =>
Json.Decode.{
buy: json |> field("buy", float),
sell: json |> field("sell", float),
symbol: json |> field("symbol", string),
};
};
[%bs.raw {|require('./index.css')|}];
ReactDOMRe.renderToElementWithId(
<App />,
"root",
);
let component = ReasonReact.statelessComponent("Ticker");
let make = (~coinName: string, ~coin: Coin.t, _children) => {
...component,
render: _self =>
<div className="ticker">
<h1> (ReasonReact.string(coinName)) </h1>
<dl>
<dt> (ReasonReact.string("Symbol:")) </dt>
<dd> (ReasonReact.string(coin.symbol)) </dd>
<dt> (ReasonReact.string("Sell:")) </dt>
<dd> (ReasonReact.string(string_of_float(coin.sell))) </dd>
<dt> (ReasonReact.string("Buy:")) </dt>
<dd> (ReasonReact.string(string_of_float(coin.buy))) </dd>
</dl>
</div>,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment