Last active
April 27, 2019 01:46
-
-
Save dpwiz/d914d2167b6008ee93fb to your computer and use it in GitHub Desktop.
A minimal Elm application with AJAX and Virtual DOM.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Debug | |
import Graphics.Input as Input | |
import Html | |
import Html (..) | |
import Html.Attributes (..) | |
import Html.Events (..) | |
import Html.Tags (..) | |
import Http | |
import Window | |
-- Application state | |
type State = {} | |
initialState = {} | |
-- Application-wide actions (that trigger state change) | |
data Action | |
= NoOp | |
| GotResult | |
-- Entry point | |
main : Signal Element | |
main = scene <~ state ~ Window.dimensions | |
-- "Fold-from-past" for incoming application signals | |
state : Signal State | |
state = foldp step initialState <| merges [ actions.signal | |
, gotResult <~ fetchStuff clicky.signal | |
] | |
-- A "channel" to trigger a change in app state directly | |
actions : Input.Input Action | |
actions = Input.input NoOp | |
-- The Magic is happening here | |
------------------------------ | |
-- A channel to trigger a HTTP request. | |
-- Heads up! The type should provide at least two distinct values if you don't want | |
-- your request to fire right upon application launch. () however is perfectly fine | |
-- for initial query (for settings and such). | |
clicky : Input.Input (Maybe String) | |
clicky = Input.input Nothing | |
-- Transform a stream of requests to a stream of responses. | |
fetchStuff : Signal (Maybe String) -> Signal () | |
fetchStuff querySource = | |
let makeQuery q = | |
case Debug.watch "Query" q of | |
Nothing -> Http.get "" | |
Just payload -> Http.post "/stuff.json" payload | |
getResult r = | |
case Debug.watch "Result" r of | |
_ -> () | |
in getResult <~ Http.send (lift makeQuery querySource) | |
-- Transform a response to a application event | |
gotResult : () -> Action | |
gotResult () = GotResult | |
-- Boring stuff | |
--------------- | |
-- Update application state due to incoming event | |
step : Action -> State -> State | |
step a s = case Debug.watch "State" s of | |
_ -> s | |
-- Elm container for rendered DOM | |
scene : State -> (Int, Int) -> Element | |
scene s (w,h) = Html.toElement w h <| view s | |
-- Render application state as DOM | |
view : State -> Html | |
view s = p [] | |
[ button [ onclick clicky.handle (always <| Just "hello there") ] [ text "click me" ] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment