Hi Elm gang! Super enjoying the language, finally hit my first serious roadblock, wondering if anyone can help.
I’m trying to decode this JSON file: https://recipes.coopcloud.tech/recipes.json
Everything is working fine, except for the versions
key for each “recipe”, which has a structure like this:
{
"adapt_authoring": {
...
"versions": [
{
"0.1.0+0.10.5": {
"app": {
"digest": "f6d5407",
"image": "3wordchant/adaptauthoring",
"tag": "0.10.5"
},
"db": {
"digest": "9a5e0d0",
"image": "mongo",
"tag": "3.7"
}
}
},
{
"0.2.0+0.11.1": {
"app": {
"digest": "unknown",
"image": "coop-cloud-chaos-patchs/adapt_authoring",
"tag": "0.11.1"
},
"db": {
"digest": "9a5e0d0",
"image": "mongo",
"tag": "3.7"
}
}
}
],
}
}
...
}
I’d like to parse this into the versions
property of my custom App
type:
type alias App =
{ name : String
, category : String
, repository : Maybe String
, versions : List String
, icon : Maybe String
, status : Int
, slug : String
, default_branch : String
, website : Maybe String
, description : Maybe String
}
So, discarding the contents of each JSON object, and just looking at the keys to build the List String
, which in this example would look like [ "0.1.0+0.10.5", "0.2.0+0.11.1" ]
.
I’m trying to use Json.Decode.Value to ignore the contents of the objects in versions
, but I get an error from the decoder:
versionsDecoder =
Decode.keyValuePairs Decode.value
|> Decode.map buildVersions
buildVersions : List ( String, Decode.Value ) -> List String
buildVersions versions =
List.map (\( version, _ ) -> version) versions
appDecoder : Decode.Decoder App
appDecoder =
Decode.succeed App
|> andMap (Decode.field "name" Decode.string)
|> andMap (Decode.field "category" Decode.string)
|> andMap (Decode.maybe (Decode.field "repository" Decode.string))
|> andMap (Decode.at [ "versions" ] versionsDecoder)
|> andMap (Decode.maybe (Decode.field "icon" Decode.string))
|> andMap (Decode.at [ "features" ] featuresDecoder)
|> andMap (Decode.succeed "")
|> andMap (Decode.field "default_branch" Decode.string)
|> andMap (Decode.maybe (Decode.field "website" Decode.string))
|> andMap (Decode.maybe (Decode.field "description" Decode.string))
appListDecoder : Decode.Decoder (List App)
appListDecoder =
Decode.keyValuePairs appDecoder
|> Decode.map buildApp
buildApp : List ( String, App ) -> List App
buildApp apps =
List.map (\( slug, app ) -> { app | slug = slug }) apps
I can’t see details of the error, and if I add Debug.log
inside buildVersions
to try and verify the contents of versions
then it doesn’t output anything to console.
When I’ve hit this kind of error before, it’s been because the JSON didn’t have the expected structure. But here, I can’t work out what’s wrong.
Any advice on either debugging the decode error, or what I should be doing to decode in this case instead?
I pushed this complete non-working example to the recipe-versions
branch of my repo; NB you’ll need to use e.g. CORS Everywhere to test locally, otherwise you’ll hit a different error because of resources failing to load.