Basic interaction between a heex file and a liveview

Hello all, rookie question here!

I am trying phoenix liveviews and wonder what I am doing wrong.

Let say that I have my home.html.heex file as following:


<%=live_render(@conn, Mapp.TestLV) %>

And my live view that is defined as:

defmodule Mapp.TestLV do
  use Phoenix.LiveView

  def render(assigns) do
    ~H"""
    <button phx-click="open"> open </button>
    <button phx-click="close"> close </button>

    <div>
    <%= if @active do %>
    OPENED
    <% else %>
    CLOSED
    <% end %>
    </div>
    """
  end

  def mount(_params, t, socket) do
    {:ok, assign(socket, :active, false)}
  end

  def handle_event("close", _params, socket) do
    {:noreply, assign(socket, :active, false)}
  end

  def handle_event("open", _params, socket) do
    {:noreply, assign(socket, :active, true)}
  end

  def handle_event(_msg, _params, socket) do
    {:noreply, socket}
  end
end

For now, everything works as expected. Now suppose that I want to insert the buttons directly inside my heex template and remove them from the liveview, that is home.html.heex is now:

<%=live_render(@conn, Mapp.TestLV) %>
<button phx-click="open"> open </button>
<button phx-click="close"> close </button>

This issue is that the buttons and the liveview do not interact anymore. Could you please explain me why, and tell what is the recommended way to achieve such tasks?

Thank you a lot :slightly_smiling_face:

Also, sorry if this question has already been answered, I could not find any similar post.

Hi, welcome.
I think what you are looking for is a component, not rendering a page.
Have a look here:
https://hexdocs.pm/phoenix_live_view/Phoenix.LiveComponent.html

1 Like

Hello and welcome!

home.html.heex is the template for the controller that is rendering the LiveView within it. If you want to use a template fort he LiveView itself, you need to create a separate heex file colocated with the LiveView’s file with the same basename, so if your LiveView is called test_lv.ex then the template must be called test_lv.html.heex. You also need to make sure to delete the render/1 function so it looks for the template!

You also have the option to mount the LiveView directly in the router without using the controller and then you won’t need live_render/2:

live "/", Mapp.TestLV, :index
1 Like

Thank you all for the answers.

I used @sodapopcan advices and decided to mount the LiveView in the router and, as @arcyfelix suggested, use LiveComponents to implement the corresponding changes depending on the events.

1 Like