Liveview modal components fail in Phoenix 1.6 when called using live_patch

My Liveview modal components are failing to open if they are called using live_patch within a span but work when called using a button with a handle-event.

I have a Liveview app that I upgraded to Phoenix 1.6.6. I have followed all of the directions laid out in this link. The app was fully functional before the upgrade:

Phoenix 1.5.x to 1.6 upgrade instructions

My app fails when I call certain modal components using a live_patch. I get this compilation error: “Stateful components must return a HEEx template (~H sigil or .heex extension)”

Yep, I’ve made sure that I replaced the ~L with ~H AND I’ve made sure that my stateful components have a div. I get this error with every single modal component whether it is stateful or stateless. I also get this error whether I put the template in an heex file or if it is defined within the .ex file.

BUT … I don’t get this error if I call the modal component via a button click that has a handle-event.

Here is what works and what doesn’t work:

FAILS (both Show and Save fail)

@impl true
  def render(assigns) do
    ~H"""
    <div id="resources">
      ...
<%= if @list_resources_action == "index" do %>
                  <span><%= live_patch "Show",
                      to: Routes.resourceform_index_path(@socket,
                      :show, resourceform) %></span><br>
                  <span><%= live_redirect "Save",
                      to: Routes.resourceform_save_resource_path(@socket,
                      :save, resourceform.id ) %></span>
                <% end %>
    ...
    </div>
"""
end

WORKS
If I call the modal component this way, then it works:

@impl true
  def render(assigns) do
  ~H"""
  <div id="authors">
...
<%= if @list_authors_action == "index" do %>
      <div class="flex-shrink-0 w-10 h-10">
           <button phx-click="show"
                phx-target={@myself}
                phx-value-id={author.id}>
                <img class="w-full h-full" src="/images/show_button.png" title="Show">
         </button>
     </div>
<% end %>
...
</div>
"""

#*****************************************************************
  # handle_event :show (glasses button)
  #*****************************************************************
  @impl true
  def handle_event("show", %{"id" => id}, socket) do
    {:noreply, push_redirect(socket, to: Routes.author_show_author_path(socket, :show_author, id), replace: true)}
  end

end

I must be missing something. Are there a set of instructions for upgrading Liveview applications to Phoenix 1.6? Was I supposed to do something else to my modal components?

If it’s a live component, aren’t you setting the id outside of the component already?

There is an upgrade guide linked at the bottom of the announcement blog post.

Thanks for the link. I had read through that before but didn’t see anything in there about live_patch and live_redirect changing.

Was your question referencing the div id? I just threw that in there to see if it would fix the problem. It did not. I took it out and I’m still getting the ~H error.

All of this code was based on the code that used to be auto-generated with LiveView. It’s just a table with “show” and “save” in the last column.

You might want to show the full code.

UPDATE
I have figured out that it is only live_modal that fails. As soon as I change it to live_component, everything works. I’m going to close this out and start a new post that more accurately describes the problem.

SOLUTION:
Arg … stupid mistake. I completely missed fixing modal_component.ex. That was what causing all of the problems. Once I updated that with the Phoenix 1.6 requirements, modal worked again.

1 Like