2017-02-17 68 views
4

鑑於以下JSON:解碼JSON到榆樹也許

[ 
    { 
    "id": 0, 
    "name": "Item 1", 
    "desc": "The first item" 
    }, 
    { 
    "id": 1, 
    "name": "Item 2" 
    } 
] 

你如何解碼是爲以下型號:

type alias Model = 
    { id : Int 
    , name : String 
    , desc : Maybe String 
    } 

回答

13

布賴恩·希克斯對JSON解碼器系列文章,你可能想要專門查看Adding New Fields to Your JSON Decoder(它處理您可能會或可能不會收到來自JSON對象的字段的場景)。首先,你可能會想要使用elm-decode-pipeline package。然後您可以使用optional function來聲明您的desc字段可能不在那裏。正如Brian在文章中指出的那樣,您可以使用來自the core Json.Decode packagemaybe解碼器,但它會產生Nothing任何失敗,而不僅僅是null。有 a nullable解碼器,如果你不想使用流水線模塊,你也可以考慮使用它。

你的解碼器可以是這個樣子:

modelDecoder : Decoder Model 
modelDecoder = 
    decode Model 
     |> required "id" int 
     |> required "name" string 
     |> optional "desc" (Json.map Just string) Nothing 

Here's a live example on Ellie.

+0

張貼我的問題後,進一步Google搜索引導我到Brian Hicks的JSON解碼器的帖子。當我回來時,我很高興看到你的回答。很高興能找到一個好的來源,這對其他人也有幫助。 –

+0

在你的最後一行中,我認爲你想''(Json.map只是字符串)''而不是'Json.map只是int)''。 –

+0

謝謝,我用'string'和Ellie例子更新了它。希望能幫助到你! – bdukes

2

布賴恩·希克斯"Adding New Fields to Your JSON Decoder"後幫我制定如下。有關工作示例,請參閱Ellie

import Html exposing (..) 
import Json.Decode as Decode exposing (Decoder) 
import Json.Decode.Pipeline as JP 
import String 

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


main = 
    Decode.decodeString (Decode.list itemDecoder) payload 
     |> toString 
     |> String.append "JSON " 
     |> text 


itemDecoder : Decoder Item 
itemDecoder = 
    JP.decode Item 
     |> JP.required "id" Decode.int 
     |> JP.required "name" Decode.string 
     |> JP.optional "desc" (Decode.map Just Decode.string) Nothing 
5

所以,如果你正在尋找不需要Json.Decode.Pipeline零依賴的解決方案。

import Json.Decode as Decode exposing (Decoder) 


modelDecoder : Decoder Model 
modelDecoder = 
    Decode.map3 Model 
     (Decode.field "id" Decode.int) 
     (Decode.field "name" Decode.string) 
     (Decode.maybe <| Decode.field "desc" Decode.string) 

如果你想這樣做,使用Model構造爲適用函子(因爲你需要更多的8個項目)。

import Json.Decode as Decode 
import Json.Decode.Extra as Decode exposing ((|:)) 


modelDecoder : Decoder Model 
modelDecoder = 
    Decode.succeed Model 
     |: Decode.field "id" Decode.int 
     |: Decode.field "name" Decode.string 
     |: Decode.maybe (Decode.field "desc" Decode.string) 

兩者都可以與List s內使用Decode.list modelDecoder。我希望應用函數在標準庫中,但您必須涉及所有* -extra庫以獲取這些功能。瞭解應用函數的工作方式將幫助您更好地理解線條,因此我建議閱讀它們。 Decode Pipeline解決方案將這個簡單的概念抽象出來,但是當您遇到需要Result.andMap或任何其他andMap時,因爲您的模塊或DSL沒有mapN,您將知道如何獲得解決方案。

+0

這應該可能是所選的響應。 Theres不需要因爲在API中有這種行爲而引入完全獨立的依賴關係。它支持開箱即用。 – jnmandal

+0

'和Then'路線的優點是你有機會綁定一個特定的錯誤消息,但是這在調試時非常有用。 ''和''應該在技術上是可並行的,因爲它是可應用的。 – toastal