Skip to content

Instantly share code, notes, and snippets.

@ronanyeah
Created February 15, 2017 13:40
Show Gist options
  • Save ronanyeah/8ea14c883325123c3e6546a36c8a1825 to your computer and use it in GitHub Desktop.
Save ronanyeah/8ea14c883325123c3e6546a36c8a1825 to your computer and use it in GitHub Desktop.
Basic elm http + json demo.
module PostExample exposing (..)
--TO RUN
--1. $ npm install -g elm
--2. $ elm-reactor
--3. Go to `http://localhost:8000/PostExample.elm`.
import Html exposing (Html, button, div, p, strong, text)
import Html.Events exposing (onClick)
import Html.Attributes exposing (style)
import Http
import Json.Decode exposing (map3, at, string, int)
-- MAIN
main =
Html.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
{ index : Int
, posts : List Post
}
-- INIT
init : ( Model, Cmd Msg )
init =
( { index = 1, posts = [] }
, getPost 1
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- MESSAGES
type Msg
= GetPost Int
| Click
| ResponseHandler (Result Http.Error Post)
-- UPDATE
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Click ->
let
newIndex =
model.index + 1
in
( { model | index = newIndex }
, getPost newIndex
)
GetPost id ->
( model
, getPost id
)
ResponseHandler res ->
case res of
Ok post ->
let
updatedPosts =
(post :: model.posts)
in
( { model | posts = updatedPosts }
, Cmd.none
)
Err err ->
let
errorPost =
{ id = model.index
, title = "ERROR"
, body = "bad response"
}
updatedPosts =
(errorPost :: model.posts)
in
( { model | posts = updatedPosts }
, Cmd.none
)
-- VIEW
view : Model -> Html Msg
view model =
let
postStyle : List ( String, String )
postStyle =
[ ( "max-width", "50vw" )
, ( "margin", "1em auto" )
, ( "padding", "1em" )
, ( "background-color", "lightblue" )
]
makePost : Post -> Html Msg
makePost post =
Html.div [ style postStyle ]
[ Html.p [] [ strong [] [ text "ID: " ], text (toString post.id) ]
, Html.p [] [ strong [] [ text "Title: " ], text post.title ]
, Html.p [] [ strong [] [ text "Body: " ], text post.body ]
]
posts : List (Html Msg)
posts =
List.map makePost model.posts
moreButton : Html Msg
moreButton =
button
[ onClick Click
, style
[ ( "margin", "1em auto" )
, ( "display", "block" )
]
]
[ text "More"
]
in
div [] (moreButton :: posts)
-- TYPES
type alias Post =
{ id : Int
, title : String
, body : String
}
-- HTTP
getPost : Int -> Cmd Msg
getPost id =
let
url =
"http://jsonplaceholder.typicode.com/posts/" ++ (toString id)
in
Http.send ResponseHandler (Http.get url responseDecoder)
responseDecoder : Json.Decode.Decoder Post
responseDecoder =
map3 Post
(at [ "id" ] int)
(at [ "title" ] string)
(at [ "body" ] string)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment