Skip to content

Instantly share code, notes, and snippets.

@ericworkman

ericworkman/Main.elm

Created Dec 19, 2017
Embed
What would you like to do?
Elm JSON decoding example
import Html exposing (..)
import Http
import Json.Decode as Decode
type alias User =
{ address: Address
, company: Company
, email: String
, id: Int
, name: String
, phone: String
, username: String
, website: String
}
type alias Address =
{ city: String
, geo: Geo
, street: String
, suite: String
, zipcode: String
}
type alias Geo =
{ lat: String
, lng: String
}
type alias Company =
{ bs: String
, catchPhrase: String
, name: String
}
type alias UserContainer =
{ users: List User }
userContainerDecoder : Decode.Decoder UserContainer
userContainerDecoder =
Decode.map UserContainer
(Decode.list userDecoder)
userDecoder : Decode.Decoder User
userDecoder =
Decode.map8 User
(Decode.field "address" addressDecoder)
(Decode.field "company" companyDecoder)
(Decode.field "email" Decode.string)
(Decode.field "id" Decode.int)
(Decode.field "name" Decode.string)
(Decode.field "phone" Decode.string)
(Decode.field "username" Decode.string)
(Decode.field "website" Decode.string)
addressDecoder : Decode.Decoder Address
addressDecoder =
Decode.map5 Address
(Decode.field "city" Decode.string)
(Decode.field "geo" geoDecoder)
(Decode.field "street" Decode.string)
(Decode.field "suite" Decode.string)
(Decode.field "zipcode" Decode.string)
geoDecoder : Decode.Decoder Geo
geoDecoder =
Decode.map2 Geo
(Decode.field "lat" Decode.string)
(Decode.field "lng" Decode.string)
companyDecoder : Decode.Decoder Company
companyDecoder =
Decode.map3 Company
(Decode.field "bs" Decode.string)
(Decode.field "catchPhrase" Decode.string)
(Decode.field "name" Decode.string)
api : String
api =
"https://jsonplaceholder.typicode.com/users"
fetchUsers : String -> Http.Request UserContainer
fetchUsers jsonApi =
Http.get jsonApi userContainerDecoder
type Msg
= GotUsers (Result Http.Error UserContainer)
| FetchUsers
update : Msg -> UserContainer -> (UserContainer, Cmd Msg)
update msg model =
case msg of
FetchUsers ->
( model, Http.send GotUsers (fetchUsers api) )
GotUsers result ->
case result of
Err httpError ->
let
_ =
Debug.log "handleUsersError" httpError
in
( model, Cmd.none )
Ok userContainer ->
( userContainer, Cmd.none )
view : UserContainer -> Html Msg
view model =
div [] [h2 [] [ text "Users"]
, div [] (List.map (renderUser) model.users)
]
renderUser : User -> Html Msg
renderUser model =
div [] [ h3 [] [ text (model.name ++ " (" ++ model.username ++ ")") ]
, p [] [ text model.email ]
, p [] [ text model.address.city ]
, p [] [ text model.company.name ]
]
init : ( UserContainer, Cmd Msg )
init =
update FetchUsers
{ users = [] }
main : Program Never UserContainer Msg
main =
Html.program
{ init = init
, subscriptions = always Sub.none
, view = view
, update = update
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment