In ELM understanding decoding JSON will take a bit of time. We can define a Decoder
as a spec on how to perform the translation from JSON
to ELM types.
In this post we will try to understand the how to decode a JSON string to ELM types. For limiting the scope we Will cover
decoding Simple Object
in this post and the others complex ones like decoding List of Objects
, decoding Union Types
, decoding JSON with optional keys
will cover in other posts.
We will use Json.Decode package from ELM core to do the decoding.
photo credit: superfluity JSON Card – Front via photopin (license)
simple object
Lets get started with defining a simple json string for easy decoding. We will also define an ELM
type to which
this json should decode into.
import Json.Decode
type alias Obj =
{ a: Int, b: String }
json =
"""
{"a": 10, "b": "abc"}
"""
Next lets define a custom decoder function called decodeObjValue
, which is composed from the different methods available in Json.Decode
library.
This will defined as per the structure of our json
and Obj
.
decodeObjValue : Json.Decode.Decoder Obj
decodeObjValue =
Json.Decode.map2 Obj
(Json.Decode.field "a" Json.Decode.int)
(Json.Decode.field "b" Json.Decode.string)
Since we have only 2 fields in the JSON string we can use Json.Decode.map2
and pass Obj
and functions to decode each field.
Our first field a
is of type Int
. So we can use (Json.Decode.field "a" Json.Decode.int)
and for b
we use (Json.Decode.field "b" Json.Decode.string)
since we are expecing b
to be of type String
Note: It is extremely important to keep the order of the fields. The decoding will fail if we try to decode the field b
first.
In Elm, all type alias’s are shorthand functions In our case Obj
is (\a b -> Obj a b)
This is the reason why we should keep the order of field. If we try to decode b
first the Obj
will receive a String as first param and it can’t accept it.
Now we defined or agreed on how to decode the incoming json. Next we need to run this decoder.
Since our input is String
we will use Json.Decode.decodeString to parse the given string and run our custom decoder.
decodeObj : String -> Obj
decodeObj json =
case Json.Decode.decodeString decodeObjValue json of
Ok obj ->
obj
Err _ ->
{a = -1, b = "Error"}
Json.Decode.decodeString
will accept the Decoder
as first argument and json string which need to decoded as second.
It returns the type Result
which we need use it with case
statement to get the exact result.
You can see the decode in action on ellie-app
Versions of Language/packages used in this post.
| Library/Language | Version |
| ---------------- |---------|
| ELM | 0.18.0 |
| core | 5.1.1 |