1

我有这个 redux-observable 史诗,它使用RxJS.ajax.post执行 POST ajax 请求,我认为它没有正确地击中我的 Elixir 路由器,因为我的 Elixir 后端没有发生任何事情。我正在以相同的方式获取正确获取类别的请求,因此我可以正确访问我的 Elixir 路由器中的其他路径。我预计问题出在我的后端 Elixir 代码而不是我的前端。我可能需要改变我的路径router.ex

当我在前端按下一个按钮时,这个对象会被发送到 elixir 后端(它以一个产品作为有效负载来调度这个动作,并点击下面的 redux-observable 史诗):

onPress = {() => {
  props.uploadProduct({
    name: props.name,
    brand: props.brand,
    description: props.description,
    image: props.image
  })

史诗:

import { ajax } from 'rxjs/observable/dom/ajax'
import { Observable } from 'rxjs'

export const uploadProductEpic = action$ =>
  action$.ofType(UPLOAD_PRODUCT)
    .mergeMap(action => {
      ajax.post('http://localhost:4000/products/', action.payload)
    })
    .map(response => uploadProductFulfilled(response))
    .catch(error => Observable.of(
      uploadProductRejected(error))
    )

长生不老药路由器:

defmodule Api.Router do
  use Plug.Router

  if Mix.env == :dev do
    use Plug.Debugger
  end
  plug :match
  plug :dispatch

  get "/categories/" do
    Api.Repo.getCategories(conn)
  end

  post "/products/:product" do
    IO.puts inspect conn
    Api.Repo.insertProduct(conn, product)
  end
end

IO.puts inspect conn不记录任何东西。所以我的 Elixir 路由器路径post "/products/:product" do没有被我的 POST 请求击中。我究竟做错了什么?

这是长生不老药功能repo.ex,我希望将产品插入我的数据库:

  def insertProduct(conn, product) do
    product = %Api.Product{name: product.name, brand: product.brand, description: product.description, image: product.image, rating: 0, numberOfVotes: 0}
    changeset = Api.Product.changeset(product)
    errors = changeset.errors
    valid = changeset.valid?
    case insert(changeset) do
      {:ok, product} ->
        conn
          |> put_resp_content_type("application/json")
          |> send_resp(200, Poison.encode!(%{
              successs: "success"
          }))
      {:error, changeset} ->
        conn
          |> put_resp_content_type("application/json")
          |> send_resp(500, Poison.encode!(%{
              failure: "Errors"
          }))
    end
  end

我是一名前端开发人员,只是想进入 Elixir,因此感谢任何指导和耐心。谢谢。

4

1 回答 1

1

您的数据是在请求正文中发送的,而不是在 URL 中,因此路由应该是:

post "/products"

您还需要在之后plug :match和之前插入 JSON 解析器plug :dispatch,如以下文档中的参数解析部分所述Plug.Router

plug :match
plug Plug.Parsers, parsers: [:json],
                   pass:  ["application/json"],
                   json_decoder: Poison
plug :dispatch

JSON 数据现在将出现在 中conn.body_params,您可以将其发送到您的函数:

post "/products" do
  Api.Repo.insertProduct(conn, conn.body_params)
end

最后,JSON 中的键是字符串,因此您需要使用括号语法而不是点来访问它们:

product = %Api.Product{name: product["name"], brand: product["brand"], description: product["description"], image: product["image"], rating: 0, numberOfVotes: 0}

我不确定您是如何定义Api.Product.changeset的,但默认的 Phoenix 约定定义了一个 2 arity 函数,该函数调用cast并从地图本身中提取数据。如果你也在做同样的事情,你可以这样做:

changeset = Api.Product.changeset(%Api.Product{}, product)
于 2017-05-22T02:43:00.733 回答