Si je cours Api.Category |> Api.Repo.all
dans iex
je reçois cette réponse dans le terminal (au fond, je reçois deux lignes de la table de base de données « catégories »):erreur en essayant de récupérer la base de données et renvoyer le résultat en réponse http
iex(1)> Api.Category |> Api.Repo.all
16:21:55.775 [debug] QUERY OK source="categories" db=5.2ms decode=6.3ms
SELECT c0."id", c0."name" FROM "categories" AS c0 []
[%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 1,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 2,
name: "Meals"}]
J'essaie de renvoyer cette réponse dans une réponse http, mais j'obtiens cette erreur (je pense qu'elle ne récupère rien de la base de données).
Poison.EncodeError at GET /categories unable to encode value: {nil, "categories"} lib/poison/encoder.ex
378 def encode(%{__struct__: _} = struct, options) do
379 Poison.Encoder.Map.encode(Map.from_struct(struct), options)
380 end
381
382 def encode(value, _options) do
383 raise Poison.EncodeError, value: value
384 end
385end
Voici ma fonction qui tente d'obtenir les entrées dans le tableau de base de données « catégories » et les retourner dans une réponse http:
def getCategories(conn) do
categories = Api.Category |> Api.Repo.all
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Poison.encode!(%{categories: categories}))
end
Qu'est-ce que je fais mal?
Je mis en place les connexions:
application.ex:
defmodule Api.Application do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
worker(__MODULE__, [], function: :run),
supervisor(Api.Repo, []),
]
opts = [strategy: :one_for_one, name: Api.Supervisor]
Supervisor.start_link(children, opts)
end
def run do
{ :ok, _ } = Plug.Adapters.Cowboy.http Api.Router, []
end
end
repo.ex a toutes mes requêtes de base de données (y compris getCategories
qui devrait être dans un contrôleur) qui m'a dit est bizarre mais bon, l'itération 1, je veux juste d'abord faire fonctionner:
defmodule Api.Repo do
use Ecto.Repo, otp_app: :api
require Ecto.Query
import Plug.Conn
def insertCategories do
categories = [
%Api.Category{name: "Grocery Products"},
%Api.Category{name: "Meals"}
]
Enum.each(categories, fn (category) -> insert(category) end)
end
def insertSubcategories do
subcategories = [
%Api.Subcategory{name: "Meat"},
%Api.Subcategory{name: "Dairy"},
%Api.Subcategory{name: "Confectionary"},
%Api.Subcategory{name: "Dessert"},
%Api.Subcategory{name: "Baking"},
%Api.Subcategory{name: "Condiments"},
%Api.Subcategory{name: "Beverages"},
%Api.Subcategory{name: "African"},
%Api.Subcategory{name: "Argentine"},
%Api.Subcategory{name: "Asian"},
%Api.Subcategory{name: "Asian Fusion"},
%Api.Subcategory{name: "BBQ"},
%Api.Subcategory{name: "Bakery"},
%Api.Subcategory{name: "Beverages"},
%Api.Subcategory{name: "Brazilian"},
%Api.Subcategory{name: "Breakfast"},
%Api.Subcategory{name: "British"},
%Api.Subcategory{name: "Cafe"},
%Api.Subcategory{name: "Cambodian"},
%Api.Subcategory{name: "Chinese"},
%Api.Subcategory{name: "Coffee and Tea"},
%Api.Subcategory{name: "Contemporary"},
%Api.Subcategory{name: "Continental"},
%Api.Subcategory{name: "Deli"},
%Api.Subcategory{name: "Desserts"},
%Api.Subcategory{name: "Drinks Only"},
%Api.Subcategory{name: "European"},
%Api.Subcategory{name: "Fijian"},
%Api.Subcategory{name: "Filipino"},
%Api.Subcategory{name: "Finger Food"},
%Api.Subcategory{name: "Fish and Chips"},
%Api.Subcategory{name: "French Fusion"},
%Api.Subcategory{name: "German"},
%Api.Subcategory{name: "Greek"},
%Api.Subcategory{name: "Grill"},
%Api.Subcategory{name: "Healthy Food"},
%Api.Subcategory{name: "Ice Cream"},
%Api.Subcategory{name: "Indian"},
%Api.Subcategory{name: "Indonesian"},
%Api.Subcategory{name: "International"},
%Api.Subcategory{name: "Irish"},
%Api.Subcategory{name: "Italian"},
%Api.Subcategory{name: "Japanese"},
%Api.Subcategory{name: "Jewish"},
%Api.Subcategory{name: "Juices"},
%Api.Subcategory{name: "Kiwi"},
%Api.Subcategory{name: "Korean"},
%Api.Subcategory{name: "Latin"},
%Api.Subcategory{name: "American"},
%Api.Subcategory{name: "Lebanese"},
%Api.Subcategory{name: "Malaysian"},
%Api.Subcategory{name: "Mediterranean"},
%Api.Subcategory{name: "Mexican"},
%Api.Subcategory{name: "Middle Eastern"},
%Api.Subcategory{name: "Mongolian"},
%Api.Subcategory{name: "Moroccan"},
%Api.Subcategory{name: "Nepalese"},
%Api.Subcategory{name: "North Indian"},
%Api.Subcategory{name: "Pacific"},
%Api.Subcategory{name: "Persian"},
%Api.Subcategory{name: "Pizza"},
%Api.Subcategory{name: "Portuguese"},
%Api.Subcategory{name: "Pub Food"},
%Api.Subcategory{name: "Seafood"},
%Api.Subcategory{name: "Singaporean"},
%Api.Subcategory{name: "South Indian"},
%Api.Subcategory{name: "Spanish"},
%Api.Subcategory{name: "Sri Lankan"},
%Api.Subcategory{name: "Steakhouse"},
%Api.Subcategory{name: "Street Food"},
%Api.Subcategory{name: "Sushi"},
%Api.Subcategory{name: "Taiwanese"},
%Api.Subcategory{name: "Thai"},
%Api.Subcategory{name: "Turkish"},
%Api.Subcategory{name: "Vietnamese"},
]
Enum.each(subcategories, fn (subcategory) -> insert(subcategory) end)
end
def insertCategorySubcategories do
categorySubcategories = [
%Api.CategorySubcategory{c_id: 1, s_id: 1},
%Api.CategorySubcategory{c_id: 1, s_id: 2},
%Api.CategorySubcategory{c_id: 1, s_id: 3},
%Api.CategorySubcategory{c_id: 1, s_id: 4},
%Api.CategorySubcategory{c_id: 1, s_id: 5},
%Api.CategorySubcategory{c_id: 1, s_id: 6},
%Api.CategorySubcategory{c_id: 1, s_id: 7},
%Api.CategorySubcategory{c_id: 2, s_id: 8},
%Api.CategorySubcategory{c_id: 2, s_id: 9},
%Api.CategorySubcategory{c_id: 2, s_id: 10},
%Api.CategorySubcategory{c_id: 2, s_id: 11},
%Api.CategorySubcategory{c_id: 2, s_id: 12},
%Api.CategorySubcategory{c_id: 2, s_id: 13},
%Api.CategorySubcategory{c_id: 2, s_id: 14},
%Api.CategorySubcategory{c_id: 2, s_id: 15},
%Api.CategorySubcategory{c_id: 2, s_id: 16},
%Api.CategorySubcategory{c_id: 2, s_id: 17},
%Api.CategorySubcategory{c_id: 2, s_id: 18},
%Api.CategorySubcategory{c_id: 2, s_id: 19},
%Api.CategorySubcategory{c_id: 2, s_id: 20},
%Api.CategorySubcategory{c_id: 2, s_id: 21},
%Api.CategorySubcategory{c_id: 2, s_id: 23},
%Api.CategorySubcategory{c_id: 2, s_id: 24},
%Api.CategorySubcategory{c_id: 2, s_id: 25},
%Api.CategorySubcategory{c_id: 2, s_id: 26},
%Api.CategorySubcategory{c_id: 2, s_id: 27},
%Api.CategorySubcategory{c_id: 2, s_id: 28},
%Api.CategorySubcategory{c_id: 2, s_id: 29},
%Api.CategorySubcategory{c_id: 2, s_id: 30},
%Api.CategorySubcategory{c_id: 2, s_id: 31},
%Api.CategorySubcategory{c_id: 2, s_id: 32},
%Api.CategorySubcategory{c_id: 2, s_id: 33},
%Api.CategorySubcategory{c_id: 2, s_id: 34},
%Api.CategorySubcategory{c_id: 2, s_id: 35},
%Api.CategorySubcategory{c_id: 2, s_id: 36},
%Api.CategorySubcategory{c_id: 2, s_id: 37},
%Api.CategorySubcategory{c_id: 2, s_id: 38},
%Api.CategorySubcategory{c_id: 2, s_id: 39},
%Api.CategorySubcategory{c_id: 2, s_id: 40},
%Api.CategorySubcategory{c_id: 2, s_id: 41},
%Api.CategorySubcategory{c_id: 2, s_id: 42},
%Api.CategorySubcategory{c_id: 2, s_id: 43},
%Api.CategorySubcategory{c_id: 2, s_id: 44},
%Api.CategorySubcategory{c_id: 2, s_id: 45},
%Api.CategorySubcategory{c_id: 2, s_id: 46},
%Api.CategorySubcategory{c_id: 2, s_id: 47},
%Api.CategorySubcategory{c_id: 2, s_id: 49},
%Api.CategorySubcategory{c_id: 2, s_id: 50},
%Api.CategorySubcategory{c_id: 2, s_id: 51},
%Api.CategorySubcategory{c_id: 2, s_id: 52},
%Api.CategorySubcategory{c_id: 2, s_id: 53},
%Api.CategorySubcategory{c_id: 2, s_id: 54},
%Api.CategorySubcategory{c_id: 2, s_id: 55},
%Api.CategorySubcategory{c_id: 2, s_id: 56},
%Api.CategorySubcategory{c_id: 2, s_id: 57},
%Api.CategorySubcategory{c_id: 2, s_id: 58},
%Api.CategorySubcategory{c_id: 2, s_id: 59},
%Api.CategorySubcategory{c_id: 2, s_id: 60},
%Api.CategorySubcategory{c_id: 2, s_id: 61},
%Api.CategorySubcategory{c_id: 2, s_id: 62},
%Api.CategorySubcategory{c_id: 2, s_id: 63},
%Api.CategorySubcategory{c_id: 2, s_id: 64},
%Api.CategorySubcategory{c_id: 2, s_id: 65},
%Api.CategorySubcategory{c_id: 2, s_id: 66},
%Api.CategorySubcategory{c_id: 2, s_id: 67},
%Api.CategorySubcategory{c_id: 2, s_id: 68},
%Api.CategorySubcategory{c_id: 2, s_id: 69},
%Api.CategorySubcategory{c_id: 2, s_id: 70},
%Api.CategorySubcategory{c_id: 2, s_id: 71},
%Api.CategorySubcategory{c_id: 2, s_id: 72},
%Api.CategorySubcategory{c_id: 2, s_id: 73},
%Api.CategorySubcategory{c_id: 2, s_id: 74},
]
Enum.each(categorySubcategories, fn (categorySubcategory) -> insert(categorySubcategory) end)
end
def getCategories(conn) do
insertCategories
categories = all Api.Category
conn
|> put_resp_content_type("application/json")
|> send_resp(200, Poison.encode!(%{categories: categories}))
end
def getSubcategories do
Api.Subcategory |> all
end
end
partie pertinente de router.ex
get "/categories/" do
[controller] = ["repo"]
Api.Repo.getCategories(conn)
end
Je passe en revue localhost:4000/categories
et obtiens l'erreur en haut.
sortie de IO.puts (catégories) - il a beaucoup de lignes dupliquées, mais c'est un autre problème lol.
16:59:54.922 [debug] QUERY OK source="categories" db=5.2ms decode=3.7ms
SELECT c0."id", c0."name" FROM "categories" AS c0 []
[%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 1,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 2,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 3,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 4,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 5,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 6,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 7,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 8,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 9,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 10,
name: "Meals"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 11,
name: "Grocery Products"},
%Api.Category{__meta__: #Ecto.Schema.Metadata<:loaded, "categories">, id: 12,
name: "Meals"}]
16:59:55.038 [error] #PID<0.340.0> running Api.Router terminated
Server: localhost:4000 (http)
Request: GET /categories
** (exit) an exception was raised:
** (Poison.EncodeError) unable to encode value: {nil, "categories"}
(poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2
(poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3
(poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
(poison) lib/poison/encoder.ex:259: anonymous fn/3 in Poison.Encoder.List.encode/3
S'il vous plaît montrer votre fonction 'index' dans le contrôleur de categories'. Le problème n'est probablement pas dans 'getCategories'. – mudasobwa
@mudasobwa Je pense que je viens d'ajouter ce que vous demandez - mon projet a une structure bizarre, donc je n'ai pas encore de contrôleur. Faites-moi savoir s'il me manque quelque chose. Bravo – BeniaminoBaggins
Mind pour mettre 'IO.inspect (categories)' juste après 'categories = all Api.Category' et vérifier ce qui sera produit? – mudasobwa