簡體   English   中英

如何將參數前端與后端API匹配

[英]How to match params frontend to backend API

我目前正在使用Elixir編寫phx API,並且可以使用Postman成功創建帳戶。 但是,當我嘗試使用React.js前端創建帳戶時,在控制台中出現了以下stacktrace。

[debug] Simple CORS request from Origin 'http://localhost:3000' is allowed
[debug] Processing with KegCopRAPI.Web.UserController.create/2
  Parameters: %{"email" => "diana@example.com", "password" => "[FILTERED]", "username" => "diana"}
  Pipelines: [:api]
[info] Sent 400 in 1ms
[debug] ** (Phoenix.ActionClauseError) could not find a matching KegCopRAPI.Web.UserController.create clause
to process request. This typically happens when there is a
parameter mismatch but may also happen when any of the other
action arguments do not match. The request parameters are:

  %{"email" => "diana@example.com", "password" => "password", "username" => "diana"}

    (kegcopr_api) lib/kegcopr_api/web/controllers/user_controller.ex:17: KegCopRAPI.Web.UserController.create(%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.33581574/1 in Plug.Logger.call/2>, #Function<0.72433304/1 in Phoenix.LiveReloader.before_send_inject_reloader/2>], body_params: %{"email" => "diana@example.com", "password" => "password", "username" => "diana"}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "POST", owner: #PID<0.413.0>, params: %{"email" => "diana@example.com", "password" => "password", "username" => "diana"}, path_info: ["api", "users"], path_params: %{}, peer: {{127, 0, 0, 1}, 58421}, port: 4000, private: %{KegCopRAPI.Web.Router => {[], %{}}, :guardian_default_claims => {:error, %CaseClauseError{term: {:error, {:badarg, ["null"]}}}}, :guardian_default_resource => nil, :phoenix_action => :create, :phoenix_controller => KegCopRAPI.Web.UserController, :phoenix_endpoint => KegCopRAPI.Web.Endpoint, :phoenix_format => "json", :phoenix_layout => {KegCopRAPI.Web.LayoutView, :app}, :phoenix_pipelines => [:api], :phoenix_router => KegCopRAPI.Web.Router, :phoenix_view => KegCopRAPI.Web.UserView, :plug_session_fetch => #Function<1.131660147/1 in Plug.Session.fetch_session/1>}, query_params: %{}, query_string: "", remote_ip: {127, 0, 0, 1}, req_cookies: %Plug.Conn.Unfetched{aspect: :cookies}, req_headers: [{"host", "localhost:4000"}, {"connection", "keep-alive"}, {"content-length", "70"}, {"accept", "application/json"}, {"origin", "http://localhost:3000"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36"}, {"authorization", "Bearer: null"}, {"content-type", "application/json"}, {"referer", "http://localhost:3000/signup"}, {"accept-encoding", "gzip, deflate, br"}, {"accept-language", "en-US,en;q=0.8"}], request_path: "/api/users", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "ka5l96ctaijuthp39krkbg597n4r75lj"}, {"access-control-allow-origin", "*"}, {"access-control-expose-headers", ""}, {"access-control-allow-credentials", "true"}, {"vary", ""}], scheme: :http, script_name: [], secret_key_base: "fIEpvi5ujSQEKgmkRpt83KiLPq068sSmvFKlWFZyNpi3nkNmUtYO24Em6cXIUblZ", state: :unset, status: nil}, %{"email" => "diana@example.com", "password" => "password", "username" => "diana"})
    (kegcopr_api) lib/kegcopr_api/web/controllers/user_controller.ex:1: KegCopRAPI.Web.UserController.action/2
    (kegcopr_api) lib/kegcopr_api/web/controllers/user_controller.ex:1: KegCopRAPI.Web.UserController.phoenix_controller_pipeline/2
    (kegcopr_api) lib/kegcopr_api/web/endpoint.ex:1: KegCopRAPI.Web.Endpoint.instrument/4
    (phoenix) lib/phoenix/router.ex:277: Phoenix.Router.__call__/1
    (kegcopr_api) lib/kegcopr_api/web/endpoint.ex:1: KegCopRAPI.Web.Endpoint.plug_builder_call/2
    (kegcopr_api) lib/plug/debugger.ex:123: KegCopRAPI.Web.Endpoint."call (overridable 3)"/2
    (kegcopr_api) lib/kegcopr_api/web/endpoint.ex:1: KegCopRAPI.Web.Endpoint.call/2
    (plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
    (cowboy) /opt/elixir/kegcopr_api/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

引起我注意的是,我需要更改React.js前端上的輸入值以匹配API接受的參數。

可以在這里找到前端。 而且我認為需要更新的文件是src / components / Input / index.js,但是我知道這是錯誤的。

    // @flow
    import React from 'react';

    type Props = {
      input: Object,
      label?: string,
      type?: string,
      placeholder?: string,
      style?: Object,
      meta: Object,
    }

    const Input = ({ input, label, type, placeholder, style, meta }: Props) =>
      <div style={{ marginBottom: '1rem' }}>
        {label && <label htmlFor={input.name}>{label}</label>}
        <input
          {...input}
          type={type}
          placeholder={placeholder}
          className="form-control"
          style={style && style}
        />
        {meta.touched && meta.error &&
          <div style={{ fontSize: '85%', color: 'rgb(255,59,48)' }}>{meta.error}</div>
        }
      </div>;

export default Input;

user_controller.ex

def create(conn, %{"user" => user_params}) do
    # with {:ok, %User{} = user} <- Accounts.create_user(user_params) do
    changeset = User.registration_changeset(%User{}, user_params)

    case Repo.insert(changeset) do
      {:ok, user} ->
        new_conn = Guardian.Plug.api_sign_in(conn, user, :access)
        jwt = Guardian.Plug.current_token(new_conn)
        # conn
        # |> put_status(:created)
        # |> put_resp_header("location", user_path(conn, :show, user))
        # |> render("show.json", user: user)
        new_conn
        |> put_status(:created)
        |> render(KegCopRAPI.SessionView, "show.json", user: user, jwt: jwt)
      {:error, changeset} ->
        conn
        |> put_status(:unprocessable_entity)
        |> render(KegCopRAPI.ChangesetView, "error.json", changeset: changeset)
    end
  end

任何和所有幫助將不勝感激。

您正在從React的頂層發送表單的字段,但是在后端控制器中,您是從"user"鍵內部獲取數據的。 您需要將從React發送的數據放在user密鑰下。 在:

export function signup(data, router) {
  return dispatch => api.post('/users', data)
    .then((response) => {
      setCurrentUser(dispatch, response);
      dispatch(reset('signup'));
      router.transitionTo('/');
    });
}

更改:

api.post('/users', data)

至:

api.post('/users', { user: data })

我看到您也在其他一些功能中發送這樣的數據,您還需要根據您在后端接受數據的方式相應地進行調整。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM