Elm:如何解码来自 JSON API 的数据
Elm: How to decode data from JSON API
我有使用 http://jsonapi.org/ 格式的数据:
{
"data": [
{
"type": "prospect",
"id": "1",
"attributes": {
"provider_user_id": "1",
"provider": "facebook",
"name": "Julia",
"invitation_id": 25
}
},
{
"type": "prospect",
"id": "2",
"attributes": {
"provider_user_id": "2",
"provider": "facebook",
"name": "Sam",
"invitation_id": 23
}
}
]
}
我有这样的模型:
type alias Model = {
id: Int,
invitation: Int,
name: String,
provider: String,
provider_user_id: Int
}
type alias Collection = List Model
我想将 json 解码成一个集合,但不知道如何。
fetchAll: Effects Actions.Action
fetchAll =
Http.get decoder (Http.url prospectsUrl [])
|> Task.toResult
|> Task.map Actions.FetchSuccess
|> Effects.task
decoder: Json.Decode.Decoder Collection
decoder =
?
如何实现解码器?谢谢
N.B。 Json.Decode docs
试试这个:
import Json.Decode as Decode exposing (Decoder)
import String
-- <SNIP>
stringToInt : Decoder String -> Decoder Int
stringToInt d =
Decode.customDecoder d String.toInt
decoder : Decoder Model
decoder =
Decode.map5 Model
(Decode.field "id" Decode.string |> stringToInt )
(Decode.at ["attributes", "invitation_id"] Decode.int)
(Decode.at ["attributes", "name"] Decode.string)
(Decode.at ["attributes", "provider"] Decode.string)
(Decode.at ["attributes", "provider_user_id"] Decode.string |> stringToInt)
decoderColl : Decoder Collection
decoderColl =
Decode.map identity
(Decode.field "data" (Decode.list decoder))
棘手的部分是使用 stringToInt
将字符串字段转换为整数。关于什么是 int 什么是字符串,我遵循了 API 示例。我们有点幸运 String.toInt
returns 和 customDecoder
预期的 Result
但有足够的灵活性,你可以变得更复杂一点并接受两者。通常你会使用 map
来处理这种事情; customDecoder
本质上是 map
对于可能会失败的函数。
另一个技巧是使用 Decode.at
进入 attributes
子对象。
我有使用 http://jsonapi.org/ 格式的数据:
{
"data": [
{
"type": "prospect",
"id": "1",
"attributes": {
"provider_user_id": "1",
"provider": "facebook",
"name": "Julia",
"invitation_id": 25
}
},
{
"type": "prospect",
"id": "2",
"attributes": {
"provider_user_id": "2",
"provider": "facebook",
"name": "Sam",
"invitation_id": 23
}
}
]
}
我有这样的模型:
type alias Model = {
id: Int,
invitation: Int,
name: String,
provider: String,
provider_user_id: Int
}
type alias Collection = List Model
我想将 json 解码成一个集合,但不知道如何。
fetchAll: Effects Actions.Action
fetchAll =
Http.get decoder (Http.url prospectsUrl [])
|> Task.toResult
|> Task.map Actions.FetchSuccess
|> Effects.task
decoder: Json.Decode.Decoder Collection
decoder =
?
如何实现解码器?谢谢
N.B。 Json.Decode docs
试试这个:
import Json.Decode as Decode exposing (Decoder)
import String
-- <SNIP>
stringToInt : Decoder String -> Decoder Int
stringToInt d =
Decode.customDecoder d String.toInt
decoder : Decoder Model
decoder =
Decode.map5 Model
(Decode.field "id" Decode.string |> stringToInt )
(Decode.at ["attributes", "invitation_id"] Decode.int)
(Decode.at ["attributes", "name"] Decode.string)
(Decode.at ["attributes", "provider"] Decode.string)
(Decode.at ["attributes", "provider_user_id"] Decode.string |> stringToInt)
decoderColl : Decoder Collection
decoderColl =
Decode.map identity
(Decode.field "data" (Decode.list decoder))
棘手的部分是使用 stringToInt
将字符串字段转换为整数。关于什么是 int 什么是字符串,我遵循了 API 示例。我们有点幸运 String.toInt
returns 和 customDecoder
预期的 Result
但有足够的灵活性,你可以变得更复杂一点并接受两者。通常你会使用 map
来处理这种事情; customDecoder
本质上是 map
对于可能会失败的函数。
另一个技巧是使用 Decode.at
进入 attributes
子对象。