Rendering JSON in Controller

I am trying to render JSON from a model in a controller with a view. I am getting the error Could not render "post.json" for LivePaper.LiveblogPostsView, please define a matching clause for render/2 or define a template at "web/templates/liveblog_posts". No templates were compiled for this module.

Every example I have seen, seems like I am doing it right. Here’s my code:

defmodule LivePaper.LiveblogPostsController do
	use LivePaper.Web, :controller

	require Logger
	alias LivePaper.Event
	alias LivePaper.Post

	def index(conn, params) do
		event = Repo.get_by(Event, link: params["link"])

		posts = Post
				|> Post.all_for_event(event.id)
				|> Repo.all
				|> Repo.preload([:user])

		render conn, "index.json", posts: posts
	end
end

defmodule LivePaper.LiveblogPostsView do
	use LivePaper.Web, :view

	def render("index.json", %{posts: posts}) do
		%{data: render_many(posts, __MODULE__, "post.json")}
	end

	def render("post.json", %{post: post}) do
		%{id: post.id}
	end
end

Is there something I am missing? It’s like its trying to pass all the posts to the render post.json and not just one.

1 Like

I’m having trouble spotting the problem by eyeballing it. Here’s what I would do in your situation, I’d add another function render("post.json", foo) (where foo is just your catch-all) and then IO.puts inspect(foo) to inspect it.

There may be a smarter way of figuring out these issues, but every time I’m hitting a case where it says I’m missing a function that I think exists, it’s always that it’s pattern matching something other than I think it should and this is my quick and dirty way of figuring out what I did wrong.

2 Likes

I did that earlier and it just has the whole posts collection instead of using a single one. My code pretty much follows all the examples i’ve seen.

1 Like

So in that case just step up and make sure that what you’re passing in really is just a list of posts and not a list of a list of posts, for example. You might be passing in something like [[post, post, post]] instead of [post, post, post].

Do you see something wrong with my controller code above?

I’d say learn to use IEx.pry, this would be a great use of something simple like IEx.pry. No doubt just some data is not what is expected (oh how I wish elixir/erlang were typed… even optionally like Elm)