Hello,
UserRecordDecoder =
D.map2 UserRecord
(D.field "id" D.int)
(D.field "level" D.int)
type alias UserRecord =
{ id : Int
, level : Int
}
will do the job however if we inverse the order of the fields like this
type alias UserRecord =
{ level : Int
, id : Int
}
for a user { id = 1, level = 10 }
you will get { id = 10, level = 1 }
Would it be better and possible not to assert that the orders of decoder and record match when decoding json and decode just according to the field names?
Tks
1 Like
This package helps with decoding json in a way that the order does not matter. It also has some more info on the subject.
2 Likes
It looks pretty good, tks!
I started to use it, documentation is great, thanks to have spent time on it!
With elm-format the nested scopes show up !
And I got a better understanding of the do notation (Decode.succeed == return ), I love functional ~
UserRecord_decoder : D.Decoder UserRecord
UserRecord_decoder =
Field.require "name" D.string
<| \name ->
Field.require "email" D.string
<| \email ->
Field.require "phone" D.string
<| \phone ->
Decode.succeed
{ email = email
, phone = phone
, name = name
}
I am glad you found it helpful. The indenting done by elm-format can be annoying sometimes, at least when you have many fields.
The do notation-ish syntax can be used with any type that has the andThen
function and can be quite useful sometimes.
Here is an example with Maybe
. (Note that Just
== return in this case)
do : Maybe a -> (a -> Maybe b) -> Maybe b
do mb continuation =
Maybe.andThen continuation mb
getSomething : String -> Dict String String -> Maybe String
getSomething key dict =
do (Dict.get key dict) <| \value1 ->
do (Dict.get value1 dict) <| \value2 ->
do (Dict.get value2 dict) <| \value3 ->
Just value3
1 Like
do : Maybe a -> (a -> Maybe b) -> Maybe b
do mb continuation =
Maybe.andThen continuation mb
getSomething acc key dict = -- acc: accumulator
do (Dict.get key dict) <| \value1 ->
do (Dict.get value1 dict) <| \value3 ->
(dict, Just value3 :: acc)
getSomethingElse acc key dict =
do (Dict.get key dict) <| \ values ->
do (Dict.get value1 dict) <| \value2 ->
(dict, Just value2 :: acc])
do (getSomething [] "Lisa" dict) <| \(dict, acc) -> getSomethingElse acc "Tom" dict -- return (dict, [ Just value2, Just value3])
In another way how can I make it composable?
Is the code above making sense?
Is there a better way?
joakin
March 15, 2019, 11:30am
7
You can also not use the alias constructor, which is what relies on order, like this:
userRecordDecoder =
D.map2 (\id level -> { id = id, level = level })
(D.field "id" D.int)
(D.field "level" D.int)
And then your decoder is independent of the type reordering it’s fields.
3 Likes
It is worth mentioning that!
system
Closed
March 25, 2019, 1:48pm
9
This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.