Skip to content

Instantly share code, notes, and snippets.

@isaacabraham
Last active July 29, 2020 23:47
Show Gist options
  • Select an option

  • Save isaacabraham/a81e1dede574f55257adff94208edb3e to your computer and use it in GitHub Desktop.

Select an option

Save isaacabraham/a81e1dede574f55257adff94208edb3e to your computer and use it in GitHub Desktop.
// Boilerplate / "Frameworky" code
module Safe =
/// A function which, when given a model, will return a new model and a command, depending on the state of the server call.
type CallHandler<'TModel, 'TMsg> = 'TModel -> 'TModel * Cmd<'TMsg>
/// Represents a message which encapsulates a client / server call and response.
type ServerMessage<'TModel, 'TMsg> = CallHandler<'TModel, 'TMsg> -> 'TMsg
/// Makes a GET to a server endpoint and handles the outgoing request and incoming response.
let inline Get<'TModel, 'TMsg> endpoint onDispatch onSuccess (serverCall:ServerMessage<'TModel,'TMsg>) input =
let onLoaded entity model = onSuccess model entity, Cmd.none
let loadCommand = Cmd.OfPromise.perform (endpoint >> Fetch.get<unit, _>) input (onLoaded >> serverCall)
serverCall (fun model -> onDispatch model, loadCommand)
// User code
type Model =
{ IsLoading : bool
TheCustomer : Customer option }
type Msg =
| LoadCustomer of Safe.CallHandler<Model, Msg>
module Api =
let getCustomerById =
Safe.Get
(sprintf "/api/customer/%i") // endpoint builder
(fun model -> { model with IsLoading = true }) // on dispatch
(fun model customer -> { model with IsLoading = false; TheCustomer = Some customer }) // on return
LoadCustomer // wrapper message
let init() = { TheCustomer = None; IsLoading = false }, Cmd.none
let update msg model =
match msg with
| LoadCustomer handle -> handle model
let view model dispatch =
div [] [
button [ OnClick (fun _ -> dispatch (Api.getCustomerById 42)) ] [ str "Load Customer" ]
div [] [ str (sprintf "Is Loading? %b" model.IsLoading) ]
match model.TheCustomer with
| Some c -> div [] [ str c.Name ]
| None -> ()
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment