web-dev-qa-db-ja.com

Elm:JSONAPIからデータをデコードする方法

私はこのデータを 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 =
  ?

デコーダーを実装するにはどうすればよいですか?ありがとう

18
Sebastian

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.toIntResultによって期待されるようにcustomDecoderを返すことは少し幸運ですが、もう少し洗練されて両方を受け入れることができる十分な柔軟性があります。通常、この種のことにはmapを使用します。 customDecoderは、失敗する可能性のある関数の場合、基本的にmapです。

もう1つのトリックは、Decode.atを使用してattributes子オブジェクトの内部に入ることでした。

24
mgold