Reputation: 21037
Struggling to find the right way to complete my Decoder. I start with data of the form
[{_id:'interests', [{obj1}, {obj1}]}
,{_id:'countries', [{obj2}, {...}]}
,{_id:'sections', [{obj3}, {...}]}]
I want to get to a Decoder Summary
where
type alias Summary =
{ sections : List Section
, interests : List Interest
, countries : List Country
}
So far, the best I've been able to get to is an output of this sort:
[ Interests (List Interest), Countries (List Country), Sections (List Section)]
but that still requires some rather brittle pattern matching (relying upon a consistent order of the array and is therefore very problematic with 0.16). For that I use
summaryItemDecoder : String -> Decoder SummaryInfo
summaryItemDecoder item =
let dec =
case item of
"sections" -> Json.map Sections sectionsDecoder
"interests" -> Json.map Interests interestsDecoder
"countries" -> Json.map Countries countriesDecoder
in ("data" := dec)
listSummaryDecoder : Decoder (List SummaryInfo)
listSummaryDecoder =
("_id" := string) `Json.andThen` summaryItemDecoder
|> list
Full code here. Grateful for some final tips
Upvotes: 3
Views: 596
Reputation: 2923
You can fold the list of information into a Summary.
type Interest = Interest
type Section = Section
type Country = Contry
type Info = Interests (List Interest) | Countries (List Country) | Sections (List Section)
type alias Summary =
{ sections : List Section
, interests : List Interest
, countries : List Country
}
emptySummary : Summary
emptySummary =
{ sections = []
, interests = []
, countries = []
}
toSummary : List Info -> Summary
toSummary xs =
let
insert info sum =
case info of
Sections ss -> { sum | sections = ss }
Interests is -> { sum | interests = is }
Countries cs -> { sum | countries = cs }
in
List.foldl insert emptySummary xs
infoList : List Info
infoList = []
summary = toSummary infoList
Upvotes: 0
Reputation: 366
I'm not sure you can do much better; you are attempting to parse a format that can express things you cannot represent in your types, so your only option is to fail.
To satisfy the pattern matching gods, perhaps drop an otherwise
clause in featuring the fail
decoder? (http://package.elm-lang.org/packages/elm-lang/core/3.0.0/Json-Decode#fail)
Upvotes: 2