Hi! Very new to learning Elm and was wondering if someone could help simplify a bit of JSON decoding logic or maybe explain the best practice to do what I’ve done.
Basic problem is I have a JSON endpoint that gives me a list of Tasks. Each task has common fields and either some physical data or some virtual data. I have modelled this as below:
type alias Task = { name : String, location : TaskLocation}
type TaskLocation = PhysicalTask Address | VirtualTask WebAddress
type alias Address = { street : String }
type alias WebAddress = { url : String }
Then to decode, I can use Json.Decode.andThen
to read the "type"
field in the JSON and parse the relevant data into the matching type.
taskDecoder : Json.Decode.Decoder Task
taskDecoder =
Json.Decode.map2 Task
(Json.Decode.field "name" Json.Decode.string)
taskTypeDecoder
taskTypeDecoder : Json.Decode.Decoder TaskLocation
taskTypeDecoder =
Json.Decode.field "type" Json.Decode.string
|> Json.Decode.andThen
(\taskType ->
case taskType of
"physical" ->
Json.Decode.map PhysicalTask <| Json.Decode.field "physical" physicalDecoder
"virtual" ->
Json.Decode.map VirtualTask <| Json.Decode.field "virtual" virtualDecoder
_ ->
Json.Decode.fail <| "unknown task type: " ++ taskType
)
So my question is: Is there some way to do this without using the type
field? If so, is it worth refactoring to use it?
It feels like I should be able to use Json.Decode.oneOf
but that seems to be used for one field only. I’m pretty new to functional programming so could be wrong about that.