Elm:解析JSON中的状态代码(带有潜在错误消息)
我一直很难用Elm解析JSON。我似乎已经掌握了基本知识,但由于某种原因,这一小块JSON让我感到困惑 下面是一个场景:我正在发布一个JSON API,该API将以以下两种格式之一返回: 如果请求成功: 如果失败: 我试图将此JSON响应编码为以下数据类型:Elm:解析JSON中的状态代码(带有潜在错误消息),json,elm,Json,Elm,我一直很难用Elm解析JSON。我似乎已经掌握了基本知识,但由于某种原因,这一小块JSON让我感到困惑 下面是一个场景:我正在发布一个JSON API,该API将以以下两种格式之一返回: 如果请求成功: 如果失败: 我试图将此JSON响应编码为以下数据类型: type RequestStatus = Success | Error String type alias CreatePostResponse = { status : RequestStatus , post :
type RequestStatus = Success | Error String
type alias CreatePostResponse =
{ status : RequestStatus
, post : Maybe Post }
到目前为止,我运气不好。我一直在阅读教程和指南,但似乎都没有把我带到正确的地方。以下是我目前掌握的代码:
createPostResponse : Decoder CreatePostResponse
createPostResponse =
succeed CreatePostResponse
|: (("status" := string) `andThen` (("error" := string) `andThen` decodeStatus))
|: maybe ("post" := post)
decodeStatus : String -> String -> Decoder RequestStatus
decodeStatus status errorMessage =
succeed (case status of
"success" -> Success
"error" -> Error errorMessage
_ -> Error "unknown")
显然,这会产生各种类型的错误,并且无法编译,但是我还没有找到一种好的方法将字符串从“message”字段获取到RequestStatus
类型中
有人有什么想法吗?这里有一个小的工作代码,它可以完成您想要的工作。为了具体起见,我冒昧地为
Post
类型假设了一个基本形状
import Json.Decode exposing (..)
type alias Post = { title: String, body: String }
type RequestStatus = Success Post | Error String
post: Decoder Post
post = object2 Post ("title" := string) ("body" := string)
requestStatusData: String -> Decoder RequestStatus
requestStatusData status =
case status of
"success" -> object1 Success ("post" := post)
"error" -> object1 Error ("message" := string)
_ -> fail <| status ++ " is not a valid value for request status"
decodeStatus : Decoder RequestStatus
decodeStatus =
("status" := string) `andThen` requestStatusData
然后
对一条记录进行解码,然后将该记录传递给一个函数,该函数执行其余的解码,因此requestStatusData
需要如下所示:
requestStatusData: String -> Decoder RequestStatus
requestStatusData
是一个成功帖子
或错误字符串
。因此,我们需要两个分支,分别与状态“success”
和“error”
关联(加上一个默认值以捕获格式错误的状态):
首先使用定义为post
的解码器解码“post”
属性,然后对结果调用object1
(Success
)的第一个参数。同样地
object2 Post ("title" := string) ("body" := string)
使用字符串
解码器解码“title”
,然后使用字符串
解码器解码“body”
,然后使用两个解码字符串作为参数调用Post
函数。因此,我们最终得出以下结论:
requestStatusData status =
case status of
"success" -> object1 Success ("post" := post)
"error" -> object1 Error ("message" := string)
_ -> fail <| status ++ " is not a valid value for request status"
而不是
RequestStatus
而不丢失任何功能(您需要稍微更改requestStatusData
,但我将留给读者作为练习…) 是的!这对我来说非常有效。非常感谢您花时间写下这篇文章(希望未来很多困惑的Elmer都会受到这篇文章的指导)。作为记录,我最终将我的RequestStatus
类型更改为aliasResult String Post
——这是一个很好的建议!很乐意帮忙。这也是巩固我对Elm的理解的一个好方法。一旦掌握了这些概念,将JSON反序列化为复杂类型将是一种很好的方式。
requestStatusData: String -> Decoder RequestStatus
requestStatusData status =
case status of
"success" -> makeSuccessWithPost
"error" -> makeErrorWithString
_ -> fail <| status ++ " is not a valid value for request status"
object1 Success ("post" := post)
object2 Post ("title" := string) ("body" := string)
requestStatusData status =
case status of
"success" -> object1 Success ("post" := post)
"error" -> object1 Error ("message" := string)
_ -> fail <| status ++ " is not a valid value for request status"
Result String Post