2016-03-07 67 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'来传递它。 –