简体   繁体   English

解码嵌套的JSON结构

[英]Decoding nested JSON structures

I'm trying playing with the source code of elmplayground and I'm trying to create a configuration json file for the blog. 我正在尝试使用elmplayground的源代码,并且正在尝试为博客创建配置json文件。 The issue I'm having at this point is that I don't know how I can decode a post/page author as a nested structure. 我现在遇到的问题是,我不知道如何将帖子/页面作者解码为嵌套结构。 What I want is that the author field in posts and pages do a reference to an author in the config.json . 我想要的是帖子和页面中的author字段在config.json引用了一个作者。

config.json: config.json:

{
  "posts": [{
    "slug": "/hello-world",
    "title": "Hello World",
    "name": "hello-world",
    "publishedDate": "2016-10-30",
    "author": "Gabriel",
    "intro": ""
  }],
  "pages": [{
    "slug": "/hello",
    "name": "index",
    "title": "Elm Playground",
    "publishedDate": "2016-09-01",
    "author": "Gabriel",
    "intro": ""
  }],
  "authors": {
    "Gabriel": {
      "name": "Gabriel Perales",
      "avatar": "..."
    }
  }
}

Type Content for pages and posts: 键入页面和帖子的内容:

type alias Content =
    { title : String
    , name : String
    , slug : String
    , publishedDate : Date
    , author : Author
    , markdown : WebData String
    , contentType : ContentType
    , intro : String
    }

Type Author: 类型作者:

type alias Author =
    { name : String
    , avatar : String
    }

Currently this is my config decoder: 当前,这是我的配置解码器:

configDecoder : Decoder Config
configDecoder =
    Decode.map2 Config
        (field "posts" <| Decode.list <| decodeContent Post)
        (field "pages" <| Decode.list <| decodeContent Page)

decodeContent : ContentType -> Decoder Content
decodeContent contentType =
    Decode.map8 Content
        (field "slug" string)
        (field "name" string)
        (field "title" string)
        (field "publishedDate" decodeDate)
        (field "author"
            (string
                -- I want to decode the author from "authors"
                -- I have tried with 
                -- (\name -> at ["authors", name] decodeCofigAuthor) but it doesn\'t work
                |> andThen (\name -> Decode.succeed <| Author name "...")
            )
        )
        (Decode.succeed RemoteData.NotAsked)
        (Decode.succeed contentType)
        (field "intro" string)


decodeConfigAuthor : Decoder Author
decodeConfigAuthor =
    Decode.map2 Author
        (field "name" string)
        (field "avatar" string)

I would start by decoding the authors, and then use andThen to pass the authors Dict into decodeContent . 我将从解码作者开始,然后使用andThen将作者Dict传递给decodeContent You can then use Decode.map to convert to author name into a lookup in the authors Dict . 然后,您可以使用Decode.map将作者姓名转换为authors Dict的查找内容。

decoder =
    (field "authors" <| Decode.dict <| authorDecoder)
        |> Decode.andThen configDecoder

configDecoder authors =
    Decode.map2 Config
        (field "posts" <| Decode.list <| decodeContent Post authors)
        (field "pages" <| Decode.list <| decodeContent Page authors)

decodeContent contentType authors =
    Decode.map8 Content
        -- …
        (field "author" (string |> Decode.map (\name -> Dict.get name authors)))
        -- …

This would change your model to use a Maybe Author , but you could also use Decode.andThen and return a Decode.fail if Dict.get returns Nothing . 这会改变你的模型使用Maybe Author ,但你也可以使用Decode.andThen并返回Decode.fail如果Dict.get返回Nothing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM