0

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?

BeniaminoBaggins
  • 11,202
  • 41
  • 152
  • 287

1 Answers1

0

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?

Steve Pallen
  • 4,417
  • 16
  • 33
  • Thanks! I have done [this Ecto getting started page](https://hexdocs.pm/ecto/getting-started.html) and [this tutorial about getting started with Elixir plug routes](https://jarredtrost.com/getting-started-with-elixir-plug-routes-3bbd1dba00e) and I am trying to mash them together to make an API that lets a frontend interface with a database, to retrieve and also insert database entries. I do want a controller but am just a bit lost. I will try to move the database queries to a controller. I thought since it is acting on the database Repo it should be in the Repo module. – BeniaminoBaggins Apr 16 '17 at 03:15
  • What I was trying to do was select all the entries in the "categories" database table and return them in the http response body. Does your example get the entries in the categories database table? – BeniaminoBaggins Apr 16 '17 at 03:20
  • I'm getting `repo Api.Repo is not started, please ensure it is part of your supervision tree` error – BeniaminoBaggins Apr 16 '17 at 03:27
  • `start_link` was my attempt to start the repo. I was going by Jose Valims comment "The repository was not started. Try Weather.Repo.start_link before querying." [here](https://github.com/elixir-ecto/ecto/issues/162) – BeniaminoBaggins Apr 16 '17 at 03:34
  • Yes, my example loads all the categories in the database. The repo only needs to be started once at startup. So you would not do that in a get function that can get called over and over. You should be starting the repo in the supervisor. You may want to create a phoenix project as an example since it creates everything in the right place. – Steve Pallen Apr 16 '17 at 04:56