Elm:
Working with JSON
How to:
Elm treats JSON handling with explicitness and safety, primarily using the Json.Decode
and Json.Encode
modules. To start working with JSON, you first need to define a decoder for your data type. Let’s assume we’re dealing with a simple user profile object.
Firstly, define your Elm type:
type alias UserProfile =
{ id : Int
, name : String
, email : String
}
Decoding JSON into Elm
To decode a JSON string into the UserProfile
type, create a decoder:
import Json.Decode exposing (Decoder, int, string, field, map3)
userProfileDecoder : Decoder UserProfile
userProfileDecoder =
map3 UserProfile
(field "id" int)
(field "name" string)
(field "email" string)
To decode a JSON object:
import Json.Decode exposing (decodeString)
jsonString : String
jsonString =
"""{"id": 1, "name": "John Doe", "email": "john@example.com"}"""
decoded : Result String UserProfile
decoded =
decodeString userProfileDecoder jsonString
{- Sample Output:
Result.Ok { id = 1, name = "John Doe", email = "[email protected]" }
-}
Encoding Elm into JSON
To encode an Elm value back into JSON, leverage the Json.Encode
module.
import Json.Encode exposing (object, int, string)
encodeUserProfile : UserProfile -> String
encodeUserProfile userProfile =
object
[ ("id", int userProfile.id)
, ("name", string userProfile.name)
, ("email", string userProfile.email)
]
|> Json.Encode.encode 0
{-
Usage:
encodeUserProfile { id = 1, name = "John Doe", email = "[email protected]" }
Sample Output:
"{"id":1,"name":"John Doe","email":"[email protected]"}"
-}
Third-Party Libraries
Elm packages like elm-json-decode-pipeline
can simplify the creation of decoders using a pipeline style, which is especially handy for decoding complex objects.
First, add the library to your project:
elm install NoRedInk/elm-json-decode-pipeline
Then, you can simplify the decoder definition as follows:
import Json.Decode exposing (int, string, succeed)
import Json.Decode.Pipeline exposing (required, decode)
userProfileDecoder : Decoder UserProfile
userProfileDecoder =
decode UserProfile
|> required "id" int
|> required "name" string
|> required "email" string
{- Use this decoder as before with decodeString to decode JSON strings. -}
This approach simplifies the decoder, making the code cleaner and more maintainable, especially as the data structures become more complex.