Created
December 19, 2017 05:09
-
-
Save ericworkman/8379e5e12f6e80d2b606c4c4a4c6ee58 to your computer and use it in GitHub Desktop.
Elm JSON decoding example
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 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