protocol无法实现" [object Object]"

时间:2018-02-17 05:06:45

标签: javascript xmlhttprequest elixir ecto

我试图从前端到后端发送一个对象和一组对象以保存到数据库。它一直在工作,但已经停止工作,因为我已经改变了前端的代码,也许我发布的数据已经变得错误。以下是javascript中我的categories对象数组的示例。

[{categoryId: 1, label: "Meat", selectedAdd:true, selectedSearch: true, value : 1}]

以下是请求的表单数据:

enter image description here

网络请求的表单数据:

brand:B.B.
name:be
description:very drab ears 
categories:[object Object]
number_of_votes:0
not_vegan_count:0
rating:0
price:344
shop:[object Object]

以下是我尝试在Elixir中获取categories对象数组并保存它们的方法:

def insert_product_categories(conn, product, product_id) do
      IO.inspect(product, label: "product")
      IO.inspect(product["categories"], label: "product[categories]")
    multi = Enum.reduce(Enum.with_index(product["categories"]), Ecto.Multi.new, fn {product_category, index}, multi -> 
      changeset = Api.ProductCategory.changeset(%Api.ProductCategory{c_id: product_category["value"], p_id: product_id})
      Ecto.Multi.insert(multi, index, changeset)
    end)

    case transaction(multi) do
      {:ok, categories} ->
        # categories here is a map with the index as key and struct as value
          {:ok, categories}
      {:error, failed_operation, failed_value, changes_so_far} ->
        {:error, failed_operation, failed_value, changes_so_far}

    end
  end

这是我的两个IO.inspect显示的内容:

product: %{"brand" => "B.B.", "categories" => "[object Object]",
  "description" => "very drab ears ", "name" => "be", "not_vegan_count" => "0",
  "number_of_votes" => "0", "price" => "344", "rating" => "0",
  "shop" => "[object Object]"}
product[categories]: "[object Object]"

以下是Api.ProductCategory.changeset

  @derive {Poison.Encoder, only: [:c_id, :p_id]}
  schema "product_categories" do
    field :c_id, :integer
    field :p_id, :integer
  end

  def changeset(product_category, params \\ %{}) do
    product_category
    |> cast(params, [:c_id, :p_id])
    |> validate_required([:c_id, :p_id])
    |> unique_constraint(:c_id, name: :unique_product_category)
  end

我的错误:

17:44:42.497 [error] #PID<0.625.0> running Api.Router terminated Server: 192.168.20.8:4000 (http) Request: POST /products
** (exit) an exception was raised:
    ** (Protocol.UndefinedError) protocol Enumerable not implemented for "[object Object]". This protocol isimplemented for: DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Postgrex.Stream, Range, Stream
        (elixir) /private/tmp/elixir-20170929-57368-1sn104i/elixir-1.5.2/lib/elixir/lib/enum.ex:1: Enumerable.impl_for!/1
        (elixir) /private/tmp/elixir-20170929-57368-1sn104i/elixir-1.5.2/lib/elixir/lib/enum.ex:116: Enumerable.reduce/3
        (elixir) lib/enum.ex:1847: Enum.map_reduce/3
        (elixir) lib/enum.ex:2697: Enum.with_index/2
        (api) lib/api/models/product_category.ex:31: Api.ProductCategory.insert_product_categories/3
        (api) lib/api/controllers/product/post_product.ex:30: Api.Controllers.PostProduct.post_product/1
        (api) lib/api/router.ex:1: Api.Router.plug_builder_call/2
        (api) lib/plug/debugger.ex:123: Api.Router.call/2

如何摆脱此错误?我可以将我的对象数组修改为Elixir代码所期望的正确格式吗?

这是我的帖子:

enter image description here

1 个答案:

答案 0 :(得分:1)

正如您对问题的评论所指出的,这不是Elixir后端的问题;问题是你的JS已将categories(和shop)值序列化为字符串"[object Object]"

JSON.stringify是您在客户端所需的方法,例如:

.post('http://192.168.20.8:4000/products', JSON.stringify(action.payload), ...

该方法的文档为javadocs,如果您不熟悉JSON,我建议使用here these之一。

一旦在客户端进行了更改,您可能(无法分辨,没有看到代码)需要调整Elixir请求处理程序以将该JSON解析为Elixir对象。图书馆Poison是社区内的常见选择,但您有很多articles