【问题标题】:Elm: How to decode data from JSON APIElm:如何从 JSON API 解码数据
【发布时间】:2017-02-13 15:19:55
【问题描述】:

我有这些数据使用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解码成一个Collection,但是不知道怎么做。

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 =
  ?

如何实现解码器?谢谢

【问题讨论】:

    标签: json elm


    【解决方案1】:

    注意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 示例。正如customDecoder 所期望的那样,String.toInt 返回了Result,我们有点幸运,但是有足够的灵活性,您可以变得更加复杂并接受两者。通常你会使用map 来处理这类事情; customDecoder 本质上是 map 用于可能失败的函数。

    另一个技巧是使用Decode.at 进入attributes 子对象。

    【讨论】:

    • 如果您还解释了如何将值映射到结果中,我会很有用。
    • OP 只询问了解码器的实现。要获得结果,请致电Json.Decode.decodeStringdecodeValue
    • := 现在是Decode.field。我已经更新了示例。
    • 最后一步现在应该是decoderColl = Decode.map identity (Decode.field "data" (Decode.list decoder))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 2017-04-11
    • 2018-12-07
    • 1970-01-01
    • 2017-01-12
    相关资源
    最近更新 更多