I use Elm 0.19.1 with NoRedInk/elm-json-decode-pipeline/1.0.0
I have an Aircraft type which is
type alias Aircraft = {name:String}
For this, I have the following decoder:
aircraftDecoder : Json.Decode.Decoder Aircraft
aircraftDecoder =
Json.Decode.succeed Aircraft
|> Json.Decode.Pipeline.required "name" Json.Decode.string
Unfortunately, the decoder is complaining me telling: "BadBody "Problem with the given value: (...)" This is because actually my area of interest if full of noise around it (from an HATEOAS api), like this:
{
"_embedded" : {
"aircrafts" : [ {
"name" : "AC01",
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts/1"
},
"aircraft" : {
"href" : "http://localhost:8080/aircrafts/1"
}
}
}, {
"name" : "AC01",
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts/2"
},
"aircraft" : {
"href" : "http://localhost:8080/aircrafts/2"
}
}
} ]
},
"_links" : {
"self" : {
"href" : "http://localhost:8080/aircrafts{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/profile/aircrafts"
}
},
"page" : {
"size" : 20,
"totalElements" : 4,
"totalPages" : 1,
"number" : 0
}
}
How can I change the code, and keep using the Pipeline, so that the decoder doesn't get lost by all this noise?
I heard something about using Json.Decode.at, but the documentation is not good enough to let me get the correct code.
As far as I can tell, the problem is that:
Aircraft
Aircraft
sAircraft
sAnd you know, for Elm Aircraft
and List Aircraft
are completely different beats (as they should be). Anyway, the solution would be a two-step thing:
Aircraft
sList Aircraft
instead of a single Aircraft
Following your code and importing at
and list
from Json.Decode
, the code might look like that:
listAircraftDecoder : Json.Decode.Decoder List Aircraft
listAircraftDecoder =
at ["_embedded", "aircrafts"] (list aircraftDecoder)
This means we're now aiming at a list of Aircraft
s and that this list is an array within the JSON. Starting at the JSON root, take the property "_embedded"
and, inside it, the property "aircrafts"
. This is a array, and Elm's list
knows how to deal with it.
Finally, we just need to tell Elm's list
to pass each element of the JSON array to a specific decoder – your aircraftDecoder
in our case.
Does that make sense?