Hello,
I am trying to implement autocomplete search. I need json url attribute. My search.json is in “/api” scope, my book_path is “/” in scope
I get that error
(UndefinedFunctionError) function nil.path/1 is undefined or private
nil.path(“/books/1”)
def render(“search.json”, %{books: books} ) do
%{data:
for book <- books do
%{
title: book.title,
url: book_path( @conn, :show, book) }
end
}
end
scope “/api”, BookTimeWeb do
pipe_through :api
get “/search”, Api.V1.SearchController, :search
end
scope “/”, BookTimeWeb do
pipe_through :browser # Use the default browser stack
resources “/books”, BookController
end
idi527
December 27, 2017, 2:26pm
2
@conn
seems to be undefined inside render
. You can compute url
for each book (in Api.V1.SearchController
?) before rendering it.
So that the render
function would become
def render("search.json", %{books: books}) do
%{data: Enum.map(books, fn %{title: title, url: url} -> %{title: title, url: url} end)}
end
thanks for reply. @conn defined inside render. I solved with string interpolation. But i didnt understand what cause that
Maybe change your router… I think paths should use lowercase
from
resources "/Books", BookController do
end
to
resources "/books", BookController
You can always display routes with
$ mix phx.routes
This will give a list of corresponding path_helper, method, path, controller, action
UPDATE : As You updated code in your post, mine is now irrelevant
i realised that typo mistake after create topic. I fixed but i still get same error.
If You don’t have access to path helper, You can use a simple string interpolation
url: book_path( @conn, :show, book)
to
url: "/books/#{book.id}"
Instead of passing in @conn
pass in YourAppName.Endpoint
module instead. It’s better than string interpolation because the knowledge of building up the urls is still contained in one place in the router.
3 Likes
Thanks it works. So code is
book_path(MyApp.Endpoint, :show, book)