BoumTAC BoumTAC - 2 months ago 9
JSON Question

ELM how to decode different value in json array

I have a JSON array with different value in the array and I don't know how to parse it. Here is an example:

[
{
"firstname": "John",
"lastname": "Doe",
"age": 30
},
{
"companyName": "Doe enterprise",
"location": "NYC",
"numberOfEmployee": 10
}
]


So my JSON is like this, the first element of the array is an user, and the second a company.
I have the equivalent in Elm:

type alias User =
{ firsname : String
, lastname : String
, age : Int
}

type alias Company =
{ companyName : String
, location : String
, numberOfEmployee : Int
}


then:
Task.perform FetchFail FetchPass (Http.get decodeData url)
.

So how do I get my
User
and
Company
pass in my
FetchPass
function ?
There is something like
Json.Decode.at
but it's for object only.
Here there a way to do something like this ?

decodeData =
Json.at [0] userDecoder
Json.at [1] companyDecoder

Answer

Json.at works for array indexes as well. First you'll need a Data type to hold the user and company:

import Json.Decode as Json exposing ((:=))

type alias Data =
  { user : User
  , company : Company
  }

And you'll need simple decoders for user and company:

userDecoder : Json.Decoder User
userDecoder =
  Json.object3 User
    ("firstname" := Json.string)
    ("lastname" := Json.string)
    ("age" := Json.int)

companyDecoder : Json.Decoder Company
companyDecoder =
  Json.object3 Company
    ("companyName" := Json.string)
    ("location" := Json.string)
    ("numberOfEmployee" := Json.int)

And finally you can use Json.at to get the values at those array indexes. The difference from your example is that you need to pass a string containing an integer index instead of an int:

dataDecoder : Json.Decoder Data
dataDecoder =
  Json.object2 Data
    (Json.at ["0"] userDecoder)
    (Json.at ["1"] companyDecoder)