【问题标题】:Poison.EncodeError unable to encode value: {"has already been taken", []}Poison.EncodeError 无法对值进行编码:{“已被占用”,[]}
【发布时间】:2017-10-31 19:11:42
【问题描述】:

我正在尝试返回无效的变更集。

什么时候做

conn
|> put_status(422)
|> put_view(Elemental.Auth.ErrorView)
|> render("422.json-api", %{data: changeset})

conn
|> put_status(422)
|> put_view(Elemental.Auth.ErrorView)
|> render(:errors, data: changeset)

使用 JaSerializer 我得到了

(Poison.EncodeError) unable to encode value: {"has already been taken", []}

这是出乎意料的。它早些时候工作。 我有{:poison, "~> 2.0"},

更新

>> d
%{errors: [shortcode: {"has invalid format", [validation: :format]}]}
iex(11)> Map.replace(d, :errors, [shortcode: Tuple.to_list(shortcode)]) |> Poison.encode
{:error,
 {:invalid, {:shortcode, ["has invalid format", [validation: :format]]}}}

【问题讨论】:

  • 它不能对显然是变更集数据一部分的元组进行编码,您必须将其更改为可以编码的内容。
  • @JustMichael 查看更新

标签: elixir phoenix-framework elixir-poison


【解决方案1】:

Poison 从来不知道如何encode 元组。您可以轻松地将元组转换为列表:

a = {"has already been taken", []}

a 
|> Tuple.to_list() # ["has already been taken", []]
|> Poison.encode!() # "[\"has already been taken\",[]]"

或者简单地使用模式匹配从元组中获取 first_entry:

{message, _list} = {"has already been taken", []}

编辑

您的代码在尝试显式显示changeset 时崩溃。避免这种情况的最佳解决方案是创建特定视图,该视图将返回 JSON,您可以在其中准备如何显示错误,例如。

def render("422.json-api", %{data: data}) do
  # data is actually changeset, which you are passing here
  errors = Enum.map(data.errors, fn {field, message} -> 
    %{field: "#{field} has error: #{message}"
  end)

  %{errors: errors}
end

【讨论】:

  • 查看更新,你是什么意思>但事实证明你只显示第一个?
  • 好的,我编辑了我的答案。避免显式使用Poison.encode! 的最简单方法是创建视图,它将为您隐式执行此操作,并且您可以完全控制要呈现的内容。
  • 因为它是一个元组,我只是提取并匹配子句并产生输出。谢谢
猜你喜欢
  • 2018-02-01
  • 2016-01-21
  • 1970-01-01
  • 1970-01-01
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
相关资源
最近更新 更多