【问题标题】:Ajax POST request not hitting Elixir router pathAjax POST 请求未命中 Elixir 路由器路径
【发布时间】:2017-10-21 13:45:38
【问题描述】:

我有这个 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,因此感谢任何指导和耐心。谢谢。

【问题讨论】:

  • 您的 JS 代码正在 POST 到 /products,而不是 /products/:product
  • 谢谢。所以如果我从router.ex 文件中删除:product,我有办法在后端获取产品对象吗?

标签: react-native ecto elixir elixir-poison


【解决方案1】:

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

post "/products"

您还需要在plug :matchplug :dispatch 之前插入JSON 解析器,如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)

【讨论】:

  • 谢谢!!它似乎仍然没有击中我的路由器。我试图在路由器中添加一个 IO.puts ,但我什么也没有记录。例如:post "/products" do IO.puts inspect conn Api.Repo.insertProduct(conn, conn.body_params) end
  • 你能在 JS 控制台中看到你的代码 ajax.post('http://localhost:4000/products/' 是否正在执行吗?您可以在 Chrome 的 DevTools 的 Network 选项卡中看到正在发出的请求。
  • 但我知道它正在运行生成 ajax POST 的代码行,因为它这行代码调度了一个确实被调度的操作.catch(error => Observable.of( uploadProductRejected(error)) )
  • 我删除了上一条消息上方的一条消息,因为它变得无关紧要。由于使用了本机反应,我无法在 chrome 开发控制台中看到网络请求,这在没有一些我没有工作的黑客的情况下是不允许的。可以确认 ajax 请求在发送 uploadProductRejected 时被发送。虽然没有错误细节。诚然,我之前没有使用过RxJS.ajax.post,所以我很想知道ajax 请求是否被正确发送。我现在正在努力。
  • 我刚刚确认它没有向/products 发送网络请求。希望很快就能让它工作,然后可以测试这个解决方案。谢谢!
猜你喜欢
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多