Using JaSerializer.PhoenixView results in no function clause matching in Plug.Conn.resp/3
mick-h opened this issue · 2 comments
Hi there,
I'm trying to use JaSerializer 0.15.0 with Phoenix 1.4.9. I've added:
use JaSerializer.PhoenixView
to the view module, then changed the render call to:
render(conn, "show.json-api", data: %{id: 1, name: "Joe", age: 43})
but when I hit the url I get the mentioned error:
Request: GET /api/users/1
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Plug.Conn.resp/3
(plug) lib/plug/conn.ex:577: Plug.Conn.resp(%Plug.Conn{adapter: {Plug.Cowboy.Conn, :...}, assigns: %{data: %{age: 43, id: 1, name: "Joe"}, layout: false}, before_send: [#Function<0.23780992/1 in Plug.Telemetry.call/2>], body_params: %{}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "GET", owner: #PID<0.464.0>, params: %{"id" => "1"}, path_info: ["api", "users", "1"], path_params: %{"id" => "1"}, port: 4000, private: %{JsonApiWeb.Router => {[], %{}}, :phoenix_action => :show, :phoenix_controller => JsonApiWeb.UserController, :phoenix_endpoint => JsonApiWeb.Endpoint, :phoenix_format => "json", :phoenix_layout => {JsonApiWeb.LayoutView, :app}, :phoenix_router => JsonApiWeb.Router, :phoenix_template => "show.json-api", :phoenix_view => JsonApiWeb.UserView, :plug_session_fetch => #Function<1.64872641/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: [{"accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"}, {"accept-encoding", "gzip, deflate, br"}, {"accept-language", "en-US,en;q=0.9"}, {"cache-control", "max-age=0"}, {"connection", "keep-alive"}, {"host", "localhost:4000"}, {"referer", "http://localhost:4000/api/users/1"}, {"upgrade-insecure-requests", "1"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}], request_path: "/api/users/1", resp_body: nil, resp_cookies: %{}, resp_headers: [{"content-type", "application/vnd.api+json; charset=utf-8"}, {"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "FbB_zZIr8nixPW8AAAAD"}], scheme: :http, script_name: [], secret_key_base: :..., state: :unset, status: nil}, 200, %{"data" => %{"attributes" => %{"age" => 43, "name" => "Joe"}, "id" => "1", "type" => "user"}, "jsonapi" => %{"version" => "1.0"}})
(phoenix) lib/phoenix/controller.ex:746: Phoenix.Controller.instrument_render_and_send/4
(json_api) lib/json_api_web/controllers/user_controller.ex:25: JsonApiWeb.UserController.show/2
(json_api) lib/json_api_web/controllers/user_controller.ex:1: JsonApiWeb.UserController.action/2
(json_api) lib/json_api_web/controllers/user_controller.ex:1: JsonApiWeb.UserController.phoenix_controller_pipeline/2
(phoenix) lib/phoenix/router.ex:288: Phoenix.Router.__call__/2
(json_api) lib/json_api_web/endpoint.ex:1: JsonApiWeb.Endpoint.plug_builder_call/2
(json_api) lib/plug/debugger.ex:122: JsonApiWeb.Endpoint."call (overridable 3)"/2
(json_api) lib/json_api_web/endpoint.ex:1: JsonApiWeb.Endpoint.call/2
(phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:40: Phoenix.Endpoint.Cowboy2Handler.init/2
(cowboy) /Users/mick/dev/code/json_api/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
(cowboy) /Users/mick/dev/code/json_api/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
(cowboy) /Users/mick/dev/code/json_api/deps/cowboy/src/cowboy_stream_h.erl:274: :cowboy_stream_h.request_process/3
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
I can see that the render function in JaSerializer.PhoenixView gets called and returns %{"data" => %{"attributes" => %{"age" => 43, "name" => "Mick"}, "id" => "1", "type" => "user"}, "jsonapi" => %{"version" => "1.0"}}
which looks fine, but it then seems to go astray in the controller code.
Am I doing something wrong here? Any help much appreciated.
Mick
It looks like something is up with the request. I would expect to see "json-api"
as the phoenix_format under the private key and "application/vnd.api+json"
in the request's accept
key. Have you verified that everything is correct in the configuration? https://github.com/vt-elixir/ja_serializer#configuration
That was it. Though interestingly, the format encoder config specified in the README:
config :phoenix, :format_encoders,
"json-api": Poison
did not work, because Poison does not have a encode_to_iodata!
function. Jason does, so when I changed it to:
config :phoenix, :format_encoders,
"json-api": Jason
it worked fine.
Thanks for the fast response!