未为“[object Object]”实现可枚举协议

protocol Enumerable not implemented for "[object Object]"

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

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

请求的表单数据如下:

网络请求表单数据:

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 代码所期望的正确格式吗?

这是我的 post:

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

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

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

该方法的文档是 here, and if you are unfamiliar with JSON, I would recommend one of these articles

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