Just started studying Elixir/Phoenix and I cant figure out why I'm getting this no function clause matching in Plug.Conn.put_resp_header/3
error.
Here's my code:
def index(conn, params) do
page = Todo |> Repo.paginate(params)
conn
|> put_status(:ok)
|> put_resp_header("x-total-count", page.total_entries)
|> render("index.json", todos: page.entries)
end
and the trace
[error] #PID<0.457.0> running TodoApp.Endpoint terminated
Server: localhost:4000 (http)
Request: GET /api/todos
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Plug.Conn.put_resp_header/3
(plug) lib/plug/conn.ex:626: Plug.Conn.put_resp_header(%Plug.Conn{adapter: {Plug.Adapters.Cowboy.Conn, :...}, assigns: %{}, before_send: [#Function<1.82124947/1 in Plug.Logger.call/2>], body_params: %{}, cookies: %Plug.Conn.Unfetched{aspect: :cookies}, halted: false, host: "localhost", method: "GET", owner: #PID<0.457.0>, params: %{}, path_info: ["api", "todos"], path_params: %{}, peer: {{127, 0, 0, 1}, 50059}, port: 4000, private: %{TodoApp.Router => {[], %{}}, :phoenix_action => :index, :phoenix_controller => TodoApp.TodoController, :phoenix_endpoint => TodoApp.Endpoint, :phoenix_format => "json", :phoenix_layout => {TodoApp.LayoutView, :app}, :phoenix_pipelines => [:api], :phoenix_router => TodoApp.Router, :phoenix_view => TodoApp.TodoView, :plug_session_fetch => #Function<1.112984571/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"}, {"cache-control", "no-cache"}, {"user-agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"}, {"postman-token", "d94524ad-4d13-e170-0ac5-021c21337895"}, {"accept", "*/*"}, {"accept-encoding", "gzip, deflate, br"}, {"accept-language", "en-US,en;q=0.9,pt;q=0.8"}], request_path: "/api/todos", resp_body: nil, resp_cookies: %{}, resp_headers: [{"cache-control", "max-age=0, private, must-revalidate"}, {"x-request-id", "1i0cddqagrkiocppi9404phdn4ajd9i7"}], scheme: :http, script_name: [], secret_key_base: "LH/fxSBb227JHpUba0PZAAYwf8N9NQCVmHe0SrnoUIXuHVUhWXeg3voq0H82qEl/", state: :unset, status: nil}, "x-total-count", 2)
(todo_app) web/controllers/todo_controller.ex:11: TodoApp.TodoController.index/2
(todo_app) web/controllers/todo_controller.ex:1: TodoApp.TodoController.action/2
(todo_app) web/controllers/todo_controller.ex:1: TodoApp.TodoController.phoenix_controller_pipeline/2
(todo_app) lib/todo_app/endpoint.ex:1: TodoApp.Endpoint.instrument/4
(phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
(todo_app) lib/todo_app/endpoint.ex:1: TodoApp.Endpoint.plug_builder_call/2
(todo_app) lib/plug/debugger.ex:99: TodoApp.Endpoint."call (overridable 3)"/2
(todo_app) lib/todo_app/endpoint.ex:1: TodoApp.Endpoint.call/2
(plug) lib/plug/adapters/cowboy/handler.ex:15: Plug.Adapters.Cowboy.Handler.upgrade/4
(cowboy) /Users/fskinner/Git/phoenix/todo_app/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
I've checked... page.entries has a value of 2 (as you can see on the trace)
Tried changing those pipes to usual Plug.Conn.put_resp_header/3
but no success.
I based that code of the create code generated by phoenix in API mode... Just like this:
def create(conn, %{"todo" => todo_params}) do
changeset = Todo.changeset(%Todo{}, todo_params)
case Repo.insert(changeset) do
{:ok, todo} ->
conn
|> put_status(:created)
|> put_resp_header("location", todo_path(conn, :show, todo))
|> render("show.json", todo: todo)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(TodoApp.ChangesetView, "error.json", changeset: changeset)
end
end
The pagination is working since the endpoint returns correctly when i remove those pipes and only keep that render func