Use the (|>) operator to build JSON decoders.
Decode a required nested field.
type alias User =
{ id : Int
, name : String
, email : String
}
userDecoder : Decoder User
userDecoder =
decode User
|> required "id" int
|> requiredAt [ "profile", "name" ] string
|> required "email" string
"""
{
"id": 123,
"email": "[email protected]",
"profile": { "name": "Sam" }
}
"""
|> decodeString userDecoder
--> Success { id = 123, name = "Sam", email = "[email protected]" }Decode a field that may be missing or have a null value. If the field is
missing, then it decodes as the fallback value. If the field is present,
then valDecoder is used to decode its value. If valDecoder fails on a
null value, then the fallback is used as if the field were missing
entirely.
type alias User =
{ id : Int
, name : String
, email : String
}
userDecoder : Decoder User
userDecoder =
decode User
|> required "id" int
|> optional "name" string "blah"
|> required "email" string
""" { "id": 123, "email": "[email protected]" } """
|> decodeString userDecoder
--> Success { id = 123, name = "blah", email = "[email protected]" }Because valDecoder is given an opportunity to decode null values before
resorting to the fallback, you can distinguish between missing and null
values if you need to:
userDecoder2 =
decode User
|> required "id" int
|> optional "name" (oneOf [ string, null "NULL" ]) "MISSING"
|> required "email" stringDecode an optional nested field.
Rather than decoding anything, use a fixed value for the next step in the
pipeline. harcoded does not look at the JSON at all.
type alias User =
{ id : Int
, name : String
, email : String
}
userDecoder : Decoder User
userDecoder =
decode User
|> required "id" int
|> hardcoded "Alex"
|> required "email" string
""" { "id": 123, "email": "[email protected]" } """
|> decodeString userDecoder
--> Success { id = 123, name = "Alex", email = "[email protected]" }Run the given decoder and feed its result into the pipeline at this point.
Consider this example.
type alias User =
{ id : Int
, name : String
, email : String
}
userDecoder : Decoder User
userDecoder =
decode User
|> required "id" int
|> custom (at [ "profile", "name" ] string)
|> required "email" string
"""
{
"id": 123,
"email": "[email protected]",
"profile": {"name": "Sam"}
}
"""
|> decodeString userDecoder
--> Success { id = 123, name = "Sam", email = "[email protected]" }Begin a decoding pipeline. This is a synonym for Json.Decode.succeed, intended to make things read more clearly.
type alias User =
{ id : Int
, email : String
, name : String
}
userDecoder : Decoder User
userDecoder =
decode User
|> required "id" int
|> required "email" string
|> optional "name" string ""Convert a Decoder (Result x a) into a Decoder a. Useful when you want
to perform some custom processing just before completing the decoding operation.
type alias User =
{ id : Int
, name : String
, email : String
}
userDecoder : Decoder User
userDecoder =
let
-- toDecoder gets run *after* all the
-- (|> required ...) steps are done.
toDecoder : Int -> String -> String -> Int -> Decoder User
toDecoder id name email version =
if version >= 2 then
succeed (User id name email)
else
fail "This JSON is from a deprecated source. Please upgrade!"
in
decode toDecoder
|> required "id" int
|> required "name" string
|> required "email" string
|> required "version" int
-- version is part of toDecoder,
-- but it is not a part of User
|> resolve
"""
{
"id": 123,
"name": "Sam",
"email": "[email protected]",
"version": 3
}
"""
|> decodeString userDecoder
--> Success { id = 123, name = "Sam", email = "[email protected]" }The examples all expect imports set up like this:
import Json.Decode.Exploration exposing (..)
import Json.Decode.Exploration.Pipeline exposing (..)For automated verification of these examples, this import is also required. Please ignore it.
import DocVerificationHelpers exposing (User)
Decode a required field.