My JSON looks like the following
{ "resp":
[ [1, "things"]
, [2, "more things"]
, [3, "even more things"]
]
}
the problem is that I can't parse the JSON tuples into Elm tuples:
decodeThings : Decoder (List (Int, String))
decodeThings = field "resp" <| list <| map2 (,) int string
It compiles, but when ran, it throws
BadPayload "Expecting an Int at _.resp[2] but instead got [3, \"even more things\"]
For some reason it reads [3, "even more things"]
as only one thing and not as tuple in JSON format.
How can I parse my JSON into a List (Int, String)
?
The accepted answer is more complicated than it needs to be. Try:
import Json.Decode as Decode
decodeTuple : Decode.Decoder (Int, String)
decodeTuple =
Decode.map2 Tuple.pair
(Decode.index 0 Decode.int)
(Decode.index 1 Decode.string)
and then, as you note, for the list
Decode.list decodeTuple
You need a decoder which turns a javascript array of size two into an Elm tuple of size two. Here is an example decoder:
arrayAsTuple2 : Decoder a -> Decoder b -> Decoder (a, b)
arrayAsTuple2 a b =
index 0 a
|> andThen (\aVal -> index 1 b
|> andThen (\bVal -> Json.Decode.succeed (aVal, bVal)))
You can then amend your original example as follows:
decodeThings : Decoder (List (Int, String))
decodeThings = field "resp" <| list <| arrayAsTuple2 int string
(Note that my example decoder does not fail if there are more than two elements, but it should get you pointed in the right direction)
I could not get either Chad Gilbert's or Simon H's solution to work with Elm 0.19. I am quite new to Elm, but this is what I could get to work:
import Json.Decode as Decode
import Json.Decode.Extra as Decode
{-| Decodes two fields into a tuple.
-}
decodeAsTuple2 : String -> Decode.Decoder a -> String -> Decode.Decoder b -> Decode.Decoder (a, b)
decodeAsTuple2 fieldA decoderA fieldB decoderB =
let
result : a -> b -> (a, b)
result valueA valueB =
(valueA, valueB)
in
Decode.succeed result
|> Decode.andMap (Decode.field fieldA decoderA)
|> Decode.andMap (Decode.field fieldB decoderB)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With