2016-03-07 66 views
0

我試圖解析JSON文件,並將其展示給用戶,這裏的簡化版本結構不匹配而解析JSON

{ 
    "posts": [{ 
    // some properties 
    comments: { 
     // some more properties 
    } 
} 

這是我的代碼,我知道這是一個很多我真的不知道爲了隔離問題要刪除什麼,每次嘗試時我都會得到一個不同的錯誤,這似乎導致我無處可去。

type Action 
    = NoOp 
    | GetPosts 
    | ShowPosts (Maybe { posts : List Post.Model }) 


init = 
    ({ posts = Nothing }, Effects.none) 


update action model = 
    case action of 
    NoOp -> 
     (model, Effects.none) 

    GetPosts -> 
     ({ model | posts = Nothing }, getPosts) 

    ShowPosts maybePosts -> 
     ({ model | posts = maybePosts }, Effects.none) 


view address model = 
    div 
    [] 
    [ button [ onClick address GetPosts ] [ text "Click to get posts!" ] 
    , viewPosts model.posts 
    ] 


viewPosts maybePosts = 
    case maybePosts of 
    Nothing -> 
     div [] [ text "No posts to display. Try clicking the button" ] 

    Just posts -> 
     ul [] (List.map Post.view posts) 



-- This is the key to map the result of the HTTP GET to an Action 
-- Note: Task.toMaybe swallows any HTTP or JSON decoding errors 


getPosts : Effects Action 
getPosts = 
    Http.get decoderColl "./posts.json" 
    |> Task.toMaybe 
    |> Task.map ShowPosts 
    |> Effects.task 


type alias PostListContainerModel = 
    { posts : List Post.Model } 


postDecoder : Decoder Post.Model 
postDecoder = 
    Decode.object5 
    Post.Model 
    ("img" := Decode.string) 
    ("text" := Decode.string) 
    ("source" := Decode.string) 
    ("date" := Decode.string) 
    ("comments" := Decode.list commentDecoder) 


commentDecoder : Decoder Comment.Model 
commentDecoder = 
    Decode.object2 
    Comment.Model 
    ("text" := Decode.string) 
    ("date" := Decode.string) 


decoderColl : Decoder PostListContainerModel 
decoderColl = 
    Decode.object1 
    PostListContainerModel 
    ("posts" := Decode.list postDecoder) 

我從編譯器收到此錯誤

功能start期待的說法是:

{ ... 
, view : 
     Signal.Address Action 
     -> { posts : Maybe { posts : List Post.Model } } 
     -> Html 
} 

但它是:

{ ... 
, view : 
     Signal.Address Action -> { posts : Maybe (List Post.Model) } -> Html 
} 

我不明白在view的定義中額外的{ posts : Maybe來自哪裏。

一些額外的背景前面的問題:Parsing nested JSON in Elm

UPDATE:

得到了榆樹社區谷歌組中的答案,這裏的要點https://gist.github.com/rundis/23d7ef6ea42842e6f527

回答

1

我認爲ShowPosts的定義越來越在辦法。你有這樣的:

ShowPosts (Maybe { posts : List Post.Model }) 

但是這或許應該是這樣的:

ShowPosts (Maybe (List Post.Model)) 

做出這樣的轉變將導致你必須更新其他一些地方,而是遵循編譯器的消息,它應該引領你到正確的地方。

其中一個需要更新的地方是getPosts,您需要從該包裝器對象中取出帖子列表。這應該是這樣簡單:

|> Task.map (ShowPosts << .posts) 
+0

嘿!謝謝:)是的,這是我嘗試過的一件事,但我得到了一個我並不真正瞭解的錯誤。我會更努力。 –

+0

我試着改變這個定義'type alias PostListContainerModel = List Post.Model',因爲它爲我提供了這種方式,但是沒有,我得到'無法找到變量'PostListContainerModel',這使我更困惑。 –

+0

我已經更新了答案,以包含一個不需要傳遞'PostListContainerModel'的例子。這對於解碼很有用,但實際上,通過更新'getPosts',你可以避免在其他地方使用'List Post.Model'來傳遞它。 –