Phoenix(1.4) Cannot find named JSON Template

Getting the error Could not render "book_v12.json" for WordApi.BookV12View, please define a matching clause for render/2 or define a template at "lib/word_api/templates/book_v12". even though I have a JSON renderer in the book_v12_view.ex file. I’m not sure why Phoenix is not matching on def render("book_v12.json", %{book: book}) do in the BookV12View module.

Depending upon API version I need to render slightly differently JSON, so the router is pointing at :indexv12 in the controller.

In the controller I render:

      book ->
        render(conn, BookV12View, "indexv12.json", %{book: book})

and in the book_v12_view.ex:

defmodule WordApi.BookV12View do
  use WordApi, :view
  alias WordApi.BookV12View

  require Logger

  def render("indexv12.json", %{book: book}) do
    %{result: render_many(book, BookV12View, "book_v12.json"),
      status: "success",
      version: "v1.2"}
  end

  def render("show.json", %{book: book}) do
    %{data: render_one(book, BookView, "book.json")}
  end

  def render("book_v12.json", %{book: book}) do
    Logger.debug("book #{inspect %{attributes: book}}")

    %{title: book.title,
    localizedTitle: book.localizedTitle,
    bid: book.uuid,
    languageId: book.languageId}
  end
end

I’m not sure why Phoenix is not matching on def render("book_v12.json", %{book: book}) do in the BookV12View module. Any ideas?

Michael

I figured it out: I need to pass-in the books as book_v12 to match the renderer.

so:

def render("indexv12.json", %{book_v12: book_v12}) do

works.

Hmm, based on the code in the original post, that should be book: book, at no place is a book_v12 binding referenced? o.O

From memory, book: book wouldn’t bind no matter what I did. I had to do book_v12: book_v12

Hmm, but it binds based on the matcher in the render function call based on what’s passed in to render(conn, BookV12View, "indexv12.json", %{book: book}) (thus the %{book: book} here), and the original post had this for those:

  def render("indexv12.json", %{book: book}) do
  def render("show.json", %{book: book}) do
  def render("book_v12.json", %{book: book}) do

All of which are book. It seems like there may be a bigger bug here if somehow book_v12 is mapping to book in the render call. o.O

TBH I’m not sure. It might’ve been a couple of bugs at the same time.

1 Like