Расшифровать вложенный ответ JSON в Elm - PullRequest
1 голос
/ 10 июля 2019

JSON-ответ

{ data: 
    { id: 1
    , name: 'item 1'
    , price: '$10'
    }
}

Файл вяза

import Json.Decode exposing (Decoder, succeed, string, int)
import Json.Decode.Pipeline exposing (optional, required)


-- TYPES --

type alias DataRes =
  { data : Item }

type alias Item =
  { id : Int
  , name : String
  , price : String 
  }


-- DECODERS --

dataResDecoder : Decoder DataRes
dataResDecoder =
  succeed DataRes
    |> required "data" itemDecoder


itemDecoder : Decoder Item
itemDecoder =
  succeed Item
    |> required "id" int
    |> required "name" string
    |> required "price" string


-- UPDATES --

type Msg
  = GotItem (Result Http.Error DataRes)

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
  case msg of
    GotItem (Ok result) ->
      updateGotItems result model


-- ACTIONS --

getItem : Int -> Cmd Msg
getItem id =
  Http.get
    { url = "https://example.com/items/" ++ id
    , expect = Http.expectString GotItem dataResDecoder
    }

Я позвонил getItem в init.

Мой вопрос касается 2-х уровней вложенного JSON, мне нужно создать 2 типа псевдонимов и 2 декодера.Если бы это было 3 уровня, то это будет всего 6 (3 типа и 3 декодера), так что больно.

Я думаю о Decode.at, но я не знаю, как заменить DataRes в GotItem (Result Http.Error DataRes) и dataResDecoder в expect = Http.expectString GotItem dataResDecoder.

Любое предложение?

Заранее спасибо.

1 Ответ

0 голосов
/ 17 июля 2019

Вы на правильном пути, например, at.Нет необходимости реплицировать всю упаковку json с оболочками структуры данных в Elm.

Похоже, все, что вам действительно нужно, это

dataResDecoder : Decoder Item
dataResDecoder =
  Decode.field "data" itemDecoder
...