Created
February 15, 2017 13:40
-
-
Save ronanyeah/8ea14c883325123c3e6546a36c8a1825 to your computer and use it in GitHub Desktop.
Basic elm http + json demo.
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
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