<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://elixirblocks.com/index.php?action=history&amp;feed=atom&amp;title=Live_view_and_handle_info</id>
	<title>Live view and handle info - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://elixirblocks.com/index.php?action=history&amp;feed=atom&amp;title=Live_view_and_handle_info"/>
	<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;action=history"/>
	<updated>2026-06-02T06:24:03Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1916&amp;oldid=prev</id>
		<title>Admin at 00:14, 29 January 2026</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1916&amp;oldid=prev"/>
		<updated>2026-01-29T00:14:46Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;amp;diff=1916&amp;amp;oldid=1915&quot;&gt;Show changes&lt;/a&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1915&amp;oldid=prev</id>
		<title>Admin: Created page with &quot;= Phoenix LiveView handle_info Guide for Web Developers =  == What is handle_info? ==  handle_info is Phoenix LiveView's way of handling messages sent to the LiveView process from outside normal user interactions (like clicks). It's your LiveView's inbox for asynchronous events.  In traditional web development, everything is request-response: user clicks, server responds, done. But LiveView processes are long-running and can receive messages from other parts of your syst...&quot;</title>
		<link rel="alternate" type="text/html" href="http://elixirblocks.com/index.php?title=Live_view_and_handle_info&amp;diff=1915&amp;oldid=prev"/>
		<updated>2026-01-29T00:11:11Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Phoenix LiveView handle_info Guide for Web Developers =  == What is handle_info? ==  handle_info is Phoenix LiveView&amp;#039;s way of handling messages sent to the LiveView process from outside normal user interactions (like clicks). It&amp;#039;s your LiveView&amp;#039;s inbox for asynchronous events.  In traditional web development, everything is request-response: user clicks, server responds, done. But LiveView processes are long-running and can receive messages from other parts of your syst...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Phoenix LiveView handle_info Guide for Web Developers =&lt;br /&gt;
&lt;br /&gt;
== What is handle_info? ==&lt;br /&gt;
&lt;br /&gt;
handle_info is Phoenix LiveView's way of handling messages sent to the LiveView process from outside normal user interactions (like clicks). It's your LiveView's inbox for asynchronous events.&lt;br /&gt;
&lt;br /&gt;
In traditional web development, everything is request-response: user clicks, server responds, done. But LiveView processes are long-running and can receive messages from other parts of your system while they're alive.&lt;br /&gt;
&lt;br /&gt;
== Basic Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_info(message, socket) do&lt;br /&gt;
  # Process the message&lt;br /&gt;
  # Update socket state if needed&lt;br /&gt;
  {:noreply, socket}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 1: Timer (sending to self) ==&lt;br /&gt;
&lt;br /&gt;
The simplest way to trigger handle_info - send a message to yourself:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    Process.send_after(self(), :refresh, 5000)&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:refresh, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;Message received after 5 seconds!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Example 2: Sending Between LiveViews with PubSub ==&lt;br /&gt;
&lt;br /&gt;
'''This is the recommended way''' to send messages between LiveViews.&lt;br /&gt;
&lt;br /&gt;
=== In PageLive (the receiver): ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Phoenix.PubSub.subscribe(App.PubSub, &amp;quot;events&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In HomeLive (the sender): ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;trigger_page&amp;quot;, _params, socket) do&lt;br /&gt;
    Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;events&amp;quot;, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;trigger_page&amp;quot;&amp;gt;Trigger Page handle_info&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Why do you need both subscribe AND broadcast? ===&lt;br /&gt;
&lt;br /&gt;
* '''Subscribe''' = &amp;quot;I want to listen to messages on the 'events' topic&amp;quot;&lt;br /&gt;
* '''Broadcast''' = &amp;quot;Send this message to everyone listening to 'events'&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Without subscribe, the LiveView won't receive broadcasts. Think of it like tuning a radio to a channel - you must tune in (subscribe) before you can hear what's being transmitted (broadcast).&lt;br /&gt;
&lt;br /&gt;
=== PubSub works with multiple LiveViews ===&lt;br /&gt;
&lt;br /&gt;
If you have 3 PageLive tabs open, all 3 will receive the broadcast. That's a feature, not a bug.&lt;br /&gt;
&lt;br /&gt;
== Example 3: Process Registration (not recommended) ==&lt;br /&gt;
&lt;br /&gt;
You can register a LiveView process with a name and send directly to it:&lt;br /&gt;
&lt;br /&gt;
=== In PageLive: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.PageLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    if connected?(socket) do&lt;br /&gt;
      Process.register(self(), :page_live_process)&lt;br /&gt;
    end&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_info(:my_message, socket) do&lt;br /&gt;
    IO.inspect(&amp;quot;handle_info received!&amp;quot;)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    Page&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== In HomeLive: ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
defmodule AppWeb.HomeLive do&lt;br /&gt;
  use AppWeb, :live_view&lt;br /&gt;
&lt;br /&gt;
  def mount(_params, _session, socket) do&lt;br /&gt;
    {:ok, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def handle_event(&amp;quot;send_to_page&amp;quot;, _params, socket) do&lt;br /&gt;
    send(:page_live_process, :my_message)&lt;br /&gt;
    {:noreply, socket}&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def render(assigns) do&lt;br /&gt;
    ~H&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    &amp;lt;button phx-click=&amp;quot;send_to_page&amp;quot;&amp;gt;Send to Page&amp;lt;/button&amp;gt;&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Problems with this approach: ===&lt;br /&gt;
&lt;br /&gt;
* Only works with ONE PageLive instance at a time&lt;br /&gt;
* Crashes if name is already taken&lt;br /&gt;
* Requires error handling bloat&lt;br /&gt;
* PageLive must be mounted first&lt;br /&gt;
&lt;br /&gt;
'''Use PubSub instead''' - it's simpler and more robust.&lt;br /&gt;
&lt;br /&gt;
== Common Sources of Messages ==&lt;br /&gt;
&lt;br /&gt;
handle_info receives messages from:&lt;br /&gt;
&lt;br /&gt;
# '''Timers''': &amp;lt;code&amp;gt;Process.send_after(self(), :tick, 1000)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''PubSub broadcasts''': &amp;lt;code&amp;gt;Phoenix.PubSub.broadcast(App.PubSub, &amp;quot;topic&amp;quot;, :msg)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''Other processes''': &amp;lt;code&amp;gt;send(liveview_pid, :msg)&amp;lt;/code&amp;gt;&lt;br /&gt;
# '''Tasks''': Background jobs completing&lt;br /&gt;
# '''GenServers''': Other parts of your application&lt;br /&gt;
&lt;br /&gt;
== Safety: Catch-all handle_info ==&lt;br /&gt;
&lt;br /&gt;
Always add a catch-all to prevent crashes from unexpected messages:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;elixir&amp;quot;&amp;gt;&lt;br /&gt;
def handle_info(msg, socket) do&lt;br /&gt;
  IO.warn(&amp;quot;Unhandled message: #{inspect(msg)}&amp;quot;)&lt;br /&gt;
  {:noreply, socket}&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Key Takeaways ==&lt;br /&gt;
&lt;br /&gt;
* handle_info handles asynchronous messages sent to your LiveView&lt;br /&gt;
* Use &amp;lt;code&amp;gt;send(self(), :msg)&amp;lt;/code&amp;gt; to send messages to yourself&lt;br /&gt;
* Use '''PubSub''' (not process registration) to send between LiveViews&lt;br /&gt;
* You must '''subscribe''' to a topic before you can receive broadcasts on that topic&lt;br /&gt;
* Always include a catch-all handle_info to handle unexpected messages&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>