考虑以下类型:
type alias Wrapper =
{ data : Data }
type alias Data =
{ name : String }
以下JSON:
{"data": {"name": "Keith"}}
如何编写解码器,允许我将HTTP响应转换为Wrapper
类型别名的实例?
我尝试了许多使用核心库Json.Decode.Pipeline和Json.Decode.Extra的方法,却没有找到可行的解决方案。
这是我最近的尝试:
dataDecoder =
succeed Data
|> andMap (field "name" Decode.string)
wrapperDecoder =
succeed Wrapper
|> andMap (field "data" dataDecoder)
结果是:
BadPayload"期望一个名为
name
的字段的对象,而是得到:{\" data \":{\" name \": \"富\"}}" {status = {code = 200,message =" OK" },headers = Dict.fromList [(" cache-control"," max-age = 0,private,must-revalidate"),(" content-type&#34 ;," application / json; charset = utf-8")],url =" http://localhost:5000//users/foo",body =" {\"数据\":{\"名称\":\"富\"}}" }
编辑:
这最终成为最终用户的问题。我 将正确的解码器传递给Http.post
,但Http.send
实际上并没有调用函数包裹Http.post
。卫生署。
答案 0 :(得分:1)
您的解码器可以正常处理您的示例输入,但是您收到的错误消息让我相信您正在尝试在Http调用中使用dataDecoder
而不是wrapperDecoder
,因为错误消息是寻找名为name
的字段。
虽然succeed
和andMap
可以用于构建解码器,但您可以使用map
:
dataDecoder : Decoder Data
dataDecoder =
Decode.map Data (field "name" string)
wrapperDecoder : Decoder Wrapper
wrapperDecoder =
Decode.map Wrapper (field "data" dataDecoder)
答案 1 :(得分:1)
正如Chad Gilbert所写,你的解码器很好:https://ellie-app.com/kDX99XRbta1/0
要进行双重检查,请在解码器中添加类型注释:
dataDecoder : Decoder Data
dataDecoder = ...
wrapperDecoder : Decoder Wrapper
wrapperDecoder = ...
如果您真的使用wrapperDecoder
(Http.post apiUrl body wrapperDecoder
),则还有一种错误可能性:您的API端点返回具有不同形状的数据,例如:
{"data": {"data": {"name": "foo"}}}
你可以仔细检查吗? (在Chrome的Web Inspector等中)