Search code examples
elixirphoenix-framework

How do I change the View module in Conn from a controller?


I have a function in my CustomerEvents controller as follows:

  def index(conn, params) do
    list = CustomerEvents.list_customer_events(params)

    conn |> put_view(MyApp.CustomersView)

    render(conn, "index.json", customers: list)
    end
  end

For this particular function the result from list_customer_events needs to go to my CustomersView, not the CustomerEvents view it tries to use by default.

From reading the documentation I thought that conn |> put_view(MyApp.CustomersView) would be enough to make that change but it doesn't seem to make any difference. When inspecting the conn object I still see:

:phoenix_view => MyApp.CustomerEventView in the private map. with my current understanding I would expect it to be :phoenix_view => MyApp.CustomerView.

How do I make this kind of change correctly?


Solution

  • The problem is that you don't pipe the conn correctly:

    conn |> put_view(MyApp.CustomersView)
    render(conn, "index.json", customers: list)
    

    All functions in elixir return a new value, meaning that when you use conn |> put_view(MyApp.CustomersView) you get a new conn, however you send to render the old one.

    To render the correct view, you either pipe everything or send the updated value:

    updated_conn = conn |> put_view(MyApp.CustomersView)
    render(updated_conn, "index.json", customers: list)
    

    or

    conn 
    |> put_view(MyApp.CustomersView)
    |> render("index.json", customers: list)