Andrew Timberlake Andrew Timberlake

Hi, I’m Andrew, a programmer and entrepreneur from South Africa,
building Mailcast for taking control of your email.
Thanks for visiting and reading.


Set a flash message from a LiveComponent

The documentation for put_flash/3 in the Phoenix LiveView docs states that the @flash assign is only copied to the parent LiveView if the component calls push_navigate/2 or push_patch/2.

So if we want to set a flash message without navigation, we can use message passing to send a flash message which the parent LiveView will set on behalf of the component.

A LiveComponent is run in the same process as the parent LiveView, so we can send a message to self() and listen to this on the parent.

defmodule MyComponent do
  use MyAppWeb, :live_component

  def handle_event("my-event", _params, socket) do
    send(self(), {:put_flash, [:info, "Flash message"]})
    {:noreply, socket}
  end
end

In the parent LiveView we can listen for this message and set the flash.

defmodule MyLiveView do
  use MyAppWeb, :live_view

  def handle_info({:put_flash, [type, message]}, socket) do
    {:noreply, put_flash(socket, type, message)}
  end
end

To make this more generic, you can add the handle_info/2 callback in your web.ex file.
For more information on how to handle global broadcasts in LiveView (and what I’m doing with the @before_compile), see How to respond to global broadcasts in Phoenix LiveView.

defmodule MyAppWeb do
  def live_view do
    quote do
      @before_compile {MyAppWeb, :live_view_handle_info_warning}

      def handle_info({:put_flash, [type, message]}, socket) do
        {:noreply, put_flash(socket, type, message)}
      end
    end

    defmacro live_view_handle_info_warning(_env) do
      quote do
        def handle_info(payload, %{view: view} = socket) do
          Logger.warning(
            "undefined handle_info in #{inspect(view)}. Unhandled message: #{inspect(payload)}"
          )

          noreply(socket)
        end
      end
    end
  end
end
21 Jan 2025

I’m available for hire, whether you need an hour to help you work through a particular problem, or help with a larger project.