phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.22k stars 933 forks source link

Flash message doesn't display when the <.flash_group flash={@flash} /> is in the root template #3354

Closed ChristopheBelpaire closed 4 months ago

ChristopheBelpaire commented 4 months ago

Environment

Actual behavior

Hello!

When I call put_flash if my component, the flash message is not displayed. My flash message is in the root layout : <.flash_group flash={@flash} /> Here is my live view :

defmodule FlashBugWeb.FlashBugLive do
  use Phoenix.LiveView
  def render(assigns) do
    ~H"""
    <button phx-click="flash">Flash!</button>
    <%= Map.get(@flash, "error") %>
    """
  end

  def mount(_params, _session, socket) do
    {:ok, socket }
  end

  def handle_params(_params, _route, socket) do
    {:noreply, socket}
  end

  def handle_event("flash", _params, socket) do
    IO.inspect("button pushed")
    socket = put_flash(socket, :error, "Should display flash")
    {:noreply, socket}
  end
end

If the module include the flash in the template, it is working fine :

  def render(assigns) do
    ~H"""
    <.flash_group flash={@flash} />
    <button phx-click="flash">Flash!</button>
    <%= Map.get(@flash, "error") %>
    """
  end

Here is a demo project with the issue : https://github.com/ChristopheBelpaire/live_view_flash_bug

Expected behavior

The flash message should be displayed when the <.flash_group flash={@flash} /> is in the root layout

Thanks!

SteffenDE commented 4 months ago

Hi! If the flash group is in the root template it is rendered outside of the LiveView. Therefore it cannot be updated by the LV. So that’s expected. Any reason why you don’t render it in the live template like usual?

ChristopheBelpaire commented 4 months ago

Hello! Thanks for the response. I wanted to have a global live flash_group, instead of having to add the flash_group in each view.

SteffenDE commented 4 months ago

Yes, that's what the app/live layout is for. If you create a new LV app with mix phx.new my_app it will create an app.html.heex file where the flash_group is rendered. This layout is included in all LiveViews that do use MyApp, :live_view.

If you have further questions feel free to create a thread in the Elixir forum, or send a message to the Elixir Slack :)

ChristopheBelpaire commented 4 months ago

Thanks for the response! In my example, I used use Phoenix.LiveView instead of use FlashBugWeb, :live_view Indeed, in works perfectly fine with FlashBugWeb, :live_view

I based my code on the documentation here : https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#content

defmodule MyAppWeb.DemoLive do
  use Phoenix.LiveView

  def render(assigns) do
    ~H"""
    Hello world!
    """
  end
end

Should it be updated ?

ChristopheBelpaire commented 4 months ago

https://github.com/phoenixframework/phoenix_live_view/pull/3356 :)