controllerrouteselixirectopostgrex

Route to controller which fetches from database and returns results in http response


I want to have a route that gets all entries from a database table and returns them.

in router.ex:

  get "/categories/" do
    [controller] = ["repo"]
    Api.Repo.getCategories(conn, controller)
  end

in repo.ex:

  def getCategories(conn, controller) do
    conn
    start_link
    categories = Api.Category |> all
    |> put_resp_content_type("application/json")
    |> send_resp(200, categories)
  end

Api.Category.ex

defmodule Api.Category do
  use Ecto.Schema

  schema "categories" do
    field :name, :string
  end

  def changeset(category, params \\ %{}) do
    category
    |> Ecto.Changeset.cast(params, [:name])
    |> Ecto.Changeset.validate_required([:name])
  end
end

I'm getting these warnings and errors:

warning: variable conn in code block has no effect as it is never returned (remove the variable or a
ssign it to _ to avoid warnings)
  lib/api/repo.ex:174

warning: variable "start_link" does not exist and is being expanded to "start_link()", please use pa
rentheses to remove the ambiguity or change the variable name
  lib/api/repo.ex:175

warning: variable "categories" does not exist and is being expanded to "categories()", please use pa
rentheses to remove the ambiguity or change the variable name
  lib/api/repo.ex:178

warning: variable "controller" is unused
  lib/api/repo.ex:173

warning: variable "categories" is unused
  lib/api/repo.ex:176


== Compilation error on file lib/api/repo.ex ==
** (CompileError) lib/api/repo.ex:178: undefined function categories/0
    (stdlib) lists.erl:1338: :lists.foreach/2
    (stdlib) erl_eval.erl:670: :erl_eval.do_apply/6

It looks like I am using categories. What am I doing wrong?


Solution

  • Your error is caused by

    categories = Api.Category |> all
    |> put_resp_content_type("application/json")
    |> send_resp(200, categories)
    

    This is a single pipeline that is assigned to categories. So, categories in send_resp(200, categories) is not set.

    To make it clear, this is another way to write the same code:

    categories = 
      Api.Category 
      |> all
      |> put_resp_content_type("application/json")
      |> send_resp(200, categories)
    

    Furthermore, the conn and start_link are misplaced. conn does nothing, and start_link usually returns a pid which is lost.

    I believe you were trying to something like:

      categories = all Api.Category
      conn
      |> put_resp_content_type("application/json")
      |> send_resp(200, categories)
    

    The whole examples looks strange. I've never see this type of stuff in a Repo module. Typically, you would find this in a controller. I can't comment on the route.ex file since I've never created routes like that before.

    Are you following an example? If so, what is it?