Decoding non-trivial JSON data in Elm

MilkJar
1 min readSep 15, 2015

Trying to decode the following JSON

[
{
"key": [
"step",
"17"
],
"value": {
"id": "1000000000",
"active": true,
"config": {
"templates": {},
"id": 17,
"name": "Somename"
}
}
},
{
"key": [
"step",
"200"
],
"value": {
"id": "1110022222",
"active": true,
"config": {
"templates": {},
"id": 200,
"name": "something"
}
}
}
]

Solution


import Graphics.Element exposing (show)
import Dict exposing (Dict)
import Json.Decode exposing (Decoder, (:=), succeed, object2, list, string, bool, dict, int, maybe, decodeString, map)
type alias Model =
{ key: List String
, values: Value
}
type alias Value =
{ id: String
, active: Bool
, config: Config
}
type alias Config =
{ templates: Maybe (Dict String String)
, id: Int
, name: String
}

— Applicative’s `pure`:
constructing : a -> Decoder a
constructing = succeed
— Applicative’s `<*>`:
apply : Decoder (a -> b) -> Decoder a -> Decoder b
apply = object2 (<|)
modelsDecoder : Decoder (List Model)
modelsDecoder = list modelDecoder
modelDecoder : Decoder Model
modelDecoder =
constructing Model
`apply` (“key” := list string)
`apply` (“value” := valueDecoder)
valueDecoder : Decoder Value
valueDecoder =
constructing Value
`apply` (“id” := string)
`apply` (“active” := bool)
`apply` (“config” := configDecoder)
configDecoder : Decoder Config
configDecoder =
constructing Config
`apply` (“templates” := maybe (dict string))
`apply` (“id” := int)
`apply` (“name” := string)
jsonString = “[{\”key\”:[\”step\”,\”17\”],\”value\”:{\”id\”:\”1000000000\”,\”active\”:true,\”config\”:{\”templates\”:{},\”id\”:17,\”name\”:\”Somename\”}}},{\”key\”:[\”step\”,\”200\”],\”value\”:{\”id\”:\”1110022222\”,\”active\”:true,\”config\”:{\”templates\”:{},\”id\”:200,\”name\”:\”something\”}}}]”main =
case (decodeString modelsDecoder jsonString) of
Ok value -> show value
Err msg -> show msg

Based on:

https://gist.github.com/codedmart/69fe8adbb30298ab511c

https://gist.github.com/jamesmacaulay/c2badacb93b091489dd4

--

--