2017-03-14 5 views
2

Ich versuche mit dem Quellcode von elmplayground zu spielen und ich versuche, eine Konfigurations-JSON-Datei für den Blog zu erstellen. Das Problem, das ich an diesem Punkt habe, ist, dass ich nicht weiß, wie ich einen Post-/Seitenautor als verschachtelte Struktur dekodieren kann. Was ich will ist, dass das author Feld in Posts und Seiten einen Verweis auf einen Autor in der config.json.Entschlüsseln verschachtelte JSON-Strukturen

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": "..." 
    } 
    } 
} 

Typ Inhalt für Seiten und Beiträge:

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

Typ Autor:

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

Derzeit ist dies meine 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) 

Antwort

3

Ich würde mit der Entschlüsselung der Autoren beginnen, und dann andThen verwenden, um die Autoren Dict in decodeContent zu übergeben. Sie können dann Decode.map verwenden, um den Namen des Autors in einen Lookup in authorsDict zu konvertieren.

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))) 
     -- … 

Dies würde Ihr Modell ändern, um eine Maybe Author zu verwenden, aber Sie auch Decode.andThen und zurück ein Decode.fail wenn Dict.get kehrt Nothing nutzen könnten.

+0

Ich werde es versuchen, aber es sieht aus wie das, was ich gesucht habe – gabrielperales