- Primitive decoders
- Primitive object fields
field
- Basic mapping
map
,map2
,mapN...
- Mapping bool to unions
- String to union
andThen
- String to Int
andThen
- Demistifying decoder mapping
nullable
fields- Absent
maybe
fields - Primitive list fields
- Object list fields
- Decoding dates
- Decoding nested objects
- Mapping more than 9 fields
Json.Decode.Extra
- Alternative decoders
oneOf
- Decoding dictionaries
- Recursive
lazy
decoders
Last active
August 1, 2024 04:10
-
-
Save joanllenas/60edc839742bb67227b4cbf21977859b to your computer and use it in GitHub Desktop.
Elm Json decoder recipes
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
-- https://ellie-app.com/3N4pnKdr7a1/2 | |
module Main exposing (main) | |
import Html exposing (Html, div, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
div [] | |
[ div [] [ "1" |> decodeString int |> toString |> text ] | |
, div [] [ """ "hello" """ |> decodeString string |> toString |> text ] | |
, div [] [ "hello" |> decodeString string |> toString |> text ] -- Err: missing double quotes in hello | |
] |
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
-- https://ellie-app.com/3N4pnKdr7a1/1 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true | |
} | |
""" | |
userDecoder = | |
map3 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) |
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
-- https://ellie-app.com/3N4pnKdr7a1/3 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", -- we want: [email protected] | |
"isPremium" : true | |
} | |
""" | |
userDecoder = | |
map3 User | |
(field "id" int) | |
(field "email" (string |> map String.toLower)) | |
(field "isPremium" bool) |
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
-- https://ellie-app.com/3N4pnKdr7a1/4 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type Membership | |
= Standard | |
| Premium | |
type alias User = | |
{ id : Int | |
, email : String | |
, membership : Membership | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true | |
} | |
""" | |
userDecoder = | |
map3 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" membership) | |
membership = | |
let | |
toMembership b = | |
case b of | |
True -> | |
Premium | |
False -> | |
Standard | |
in | |
bool |> map toMembership |
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
-- https://ellie-app.com/3N4pnKdr7a1/5 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type Gender | |
= Male | |
| Female | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, gender : Gender | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true, | |
"gender" : "male" | |
} | |
""" | |
userDecoder = | |
map4 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
(field "gender" gender) | |
gender : Decoder Gender | |
gender = | |
let | |
toGender : String -> Decoder Gender | |
toGender s = | |
case s of | |
"male" -> | |
succeed Male | |
"female" -> | |
succeed Female | |
_ -> | |
fail (s ++ " is not a valid gender") | |
in | |
string |> andThen toGender |
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
-- https://ellie-app.com/3N4pnKdr7a1/6 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
} | |
json = | |
""" | |
{ | |
"id" : "1", | |
"email" : "[email protected]", | |
"isPremium" : true | |
} | |
""" | |
userDecoder = | |
map3 User | |
(field "id" stringToInt) | |
(field "email" string) | |
(field "isPremium" bool) | |
stringToInt : Decoder Int | |
stringToInt = | |
let | |
s2Int : String -> Decoder Int | |
s2Int s = | |
case String.toInt s of | |
Ok n -> succeed n | |
Err s -> fail (s ++ " is not an Int") | |
in | |
string |> andThen s2Int | |
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
-- https://ellie-app.com/3N4pnKdr7a1/7 | |
module Main exposing (main) | |
import Html exposing (Html, text, div) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
div [] | |
[ div [] | |
[ json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
] | |
, div [] | |
[ json | |
|> decodeString userDumpDecoder | |
|> toString | |
|> text | |
] | |
] | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true | |
} | |
""" | |
userDecoder : Decoder User | |
userDecoder = | |
map3 (\a b c -> User a b c) | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
userDumpDecoder : Decoder String | |
userDumpDecoder = | |
map3 (\a b c -> "User Id: " ++ toString a ++ ", email: " ++ b ++ ", Is Premium: " ++ toString c) | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) |
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
-- https://ellie-app.com/3N4pnKdr7a1/8 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type Gender | |
= Male | |
| Female | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, gender : Maybe Gender | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true, | |
"gender" : null | |
} | |
""" | |
userDecoder = | |
map4 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
(field "gender" (nullable gender)) -- nullable does not mean absent! | |
gender : Decoder Gender | |
gender = | |
let | |
toGender : String -> Decoder Gender | |
toGender s = | |
case s of | |
"male" -> | |
succeed Male | |
"female" -> | |
succeed Female | |
_ -> | |
fail (s ++ " is not a valid gender") | |
in | |
string |> andThen toGender |
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
-- https://ellie-app.com/3N4pnKdr7a1/9 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type Gender | |
= Male | |
| Female | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, gender : Maybe Gender | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true | |
} | |
""" | |
userDecoder = | |
map4 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
(maybe (field "gender" gender)) | |
gender : Decoder Gender | |
gender = | |
let | |
toGender : String -> Decoder Gender | |
toGender s = | |
case s of | |
"male" -> | |
succeed Male | |
"female" -> | |
succeed Female | |
_ -> | |
fail (s ++ " is not a valid gender") | |
in | |
string |> andThen toGender |
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
-- https://ellie-app.com/3N4pnKdr7a1/10 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, notifications : List String | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true, | |
"notifications": ["One", "Two", "Three"] | |
} | |
""" | |
userDecoder = | |
map4 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
(field "notifications" (list string)) |
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
-- https://ellie-app.com/3N4pnKdr7a1/11 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, notifications : List Notification | |
} | |
type alias Notification = | |
{ title : String | |
, message : String | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true, | |
"notifications": [ | |
{ "title": "Hello", "message": "Welcome back" }, | |
{ "title": "Bye", "message": "See you soon" } | |
] | |
} | |
""" | |
userDecoder = | |
map4 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
(field "notifications" (list notification)) | |
notification = | |
map2 Notification | |
(field "title" string) | |
(field "message" string) |
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
-- https://ellie-app.com/3N4pnKdr7a1/12 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
import Date exposing (Date) | |
import Json.Decode.Extra exposing (date) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, dateOfBirth : Date | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true, | |
"dateOfBirth": "Mon May 21 2018 15:42:23 GMT+0200 (CEST)" | |
} | |
""" | |
userDecoder = | |
map4 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) | |
(field "dateOfBirth" date) -- OR (string |> andThen (Date.fromString >> Json.Decode.Extra.fromResult)) | |
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
-- https://ellie-app.com/3N4pnKdr7a1/13 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"account" : { | |
"isPremium" : true | |
} | |
} | |
""" | |
userDecoder = | |
map3 User | |
(field "id" int) | |
(field "email" string) | |
(at ["account", "isPremium"] bool) | |
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
-- https://ellie-app.com/3N4pnKdr7a1/14 | |
module Main exposing (main) | |
import Html exposing (Html, text) | |
import Json.Decode exposing (..) | |
import Json.Decode.Extra exposing ((|:)) | |
main : Html msg | |
main = | |
json | |
|> decodeString userDecoder | |
|> toString | |
|> text | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
, field4: Int | |
, field5: Int | |
, field6: Int | |
, field7: Int | |
, field8: Int | |
, field9: Int | |
} | |
json = | |
""" | |
{ | |
"id" : 1, | |
"email" : "[email protected]", | |
"account" : { | |
"isPremium" : true | |
}, | |
"field4": 1, | |
"field5": 1, | |
"field6": 1, | |
"field7": 1, | |
"field8": 1, | |
"field9": 1 | |
} | |
""" | |
userDecoder = | |
succeed User | |
|: field "id" int | |
|: field "email" string | |
|: at ["account", "isPremium"] bool | |
|: field "field4" int | |
|: field "field5" int | |
|: field "field6" int | |
|: field "field7" int | |
|: field "field8" int | |
|: field "field9" int | |
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
-- https://ellie-app.com/3N4pnKdr7a1/15 | |
module Main exposing (main) | |
import Html exposing (Html, div, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
div [] | |
[ div [] | |
[ json_ok | |
|> decodeString responseDecoder | |
|> toString | |
|> text | |
] | |
, div [] | |
[ json_ko | |
|> decodeString responseDecoder | |
|> toString | |
|> text | |
] | |
] | |
type alias User = | |
{ id : Int | |
, email : String | |
, isPremium : Bool | |
} | |
json_ok = | |
""" | |
{ | |
"data": { | |
"id" : 1, | |
"email" : "[email protected]", | |
"isPremium" : true | |
} | |
} | |
""" | |
json_ko = | |
""" | |
{ | |
"error": { | |
"message" : "Something went wrong" | |
} | |
} | |
""" | |
responseDecoder : Decoder (Result String User) | |
responseDecoder = | |
oneOf | |
[ field "data" userDecoder |> map Ok | |
, at [ "error", "message" ] string |> map Err | |
] | |
userDecoder = | |
map3 User | |
(field "id" int) | |
(field "email" string) | |
(field "isPremium" bool) |
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
-- https://ellie-app.com/3N4pnKdr7a1/16 | |
module Main exposing (main) | |
import Html exposing (Html, div, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString (dict string) | |
|> toString | |
|> text | |
json = """ | |
{ | |
"about_us": "Sobre nosotros", | |
"location": "Ubicación" | |
} | |
""" |
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
-- https://ellie-app.com/3N4pnKdr7a1/17 | |
module Main exposing (main) | |
import Html exposing (Html, div, text) | |
import Json.Decode exposing (..) | |
main : Html msg | |
main = | |
json | |
|> decodeString node | |
|> toString | |
|> text | |
type Node = Node String (List Node) | |
node = | |
map2 Node | |
(field "value" string) | |
((field "children" (list (lazy (\_ -> node)))) | |
|> maybe | |
|> map (Maybe.withDefault [])) | |
json = """ | |
{ | |
"value": "root", | |
"children": [ | |
{"value": "A"}, | |
{"value": "B"}, | |
{ | |
"value": "C", | |
"children": [ | |
{"value": "C-A"}, | |
{ | |
"value": "C-B", | |
"children": [ | |
{"value": "C-B-A"} | |
] | |
} | |
] | |
}, | |
{"value": "D"} | |
] | |
} | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment