rhcarvalho

rhcarvalho

How to: Sending flash messages to LiveViews from iex

Documenting one way to “broadcast” a flash message to LiveViews (mostly for fun and learning) using a rather unorthodox method.

Let’s say with no special preparation in your LiveView code – no PubSub, no callback handlers, no intention to send arbitrary flash messages to arbitrary users – you’d like to connect to a running system (e.g. iex -S mix phx.server or bin/myapp remote) and push some message onto connected browsers!

iex> search = "MyAppWeb.SomeLiveViewModule.mount"
iex> Phoenix.LiveDashboard.SystemInfo.fetch_processes(node(), search, :reductions, :desc, 10)
|> elem(0)
|> Enum.map(fn process ->
  process[:pid]
  |> then(fn pid ->
    :sys.replace_state(pid, fn state ->
       Map.update!(state, :socket, fn socket ->
        Phoenix.LiveView.put_flash(socket, :info, "Hello, #{socket.assigns.current_user.name}!")
      end)
    end) && send(pid, :ok) # Dummy message to trigger a call to `handle_changed/3` to flush new state to client 
  end)
end)

The main bits:

  • There are many ways to introspect processes, including Process.list/0 + Process.info/1, but above I went to see how Phoenix LiveDashboard implements search on the Processes tab. Thus, we’re able to find LiveViews based on name.
  • We could further filter the results, for example using :sys.get_state/1 to access the socket assigns and looking at the current logged in user to target our flash message to a specific user. Or pick a lucky LiveView process at random!
  • :sys.replace_state/2 is used to update the state of the LiveView, using the fact that it is a GenServer.
  • So far the socket was updated, but nothing happened on the browser… we need somehow to help the LiveView process to realize state has changed and needs to be sent to the client.
    There might be better ways to accomplish this, but, when the LiveView in question doesn’t implement its own handle_info callback, sending an arbitrary message works: Phoenix.LiveView.Channel.handle_info calls view_handle_info/2 which prints a warning, then eventually handle_result/3 calls handle_changed/3 and a diff with the flash message is sent to the client.

Of course, all this was just an exercise to try and demonstrate some of the introspection capabilities we have at our disposal. You should be using PubSub or other mechanisms to properly distribute messages / events.

I’m curious to learn though if my hacky steps could be improved, particularly the last bit on how to get the new state to be sent to the client. Looking forward to your comments!

Where Next?

Popular in Guides/Tuts Top

zazaian
I recently generated the boilerplate for a new mix app using the Phoenix 1.3.1 phx.new generator and realized that the structure of the w...
New
siever
I just wrote a simple guide on how you can setup a productive elixir development environment in vim. Its really easy, just a few steps. ...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
dkuku
I Created a blog post about setting up svelte with phoenix. I found it a bit tricky and the only blog post I found was written using som...
New
benwilson512
Correct if me I’m wrong, as best I can tell there aren’t any reasons to use mix run --no-halt in production vs releases. The marginal val...
New
lukertty
Install web-mode and mmm-mode first and put this in your config file: (require 'mmm-mode) (require 'web-mode) (setq mmm-global-mode 'may...
New
Jskalc
Sorry if it’s a common knowledge, but it’s something I just learned and wanted to share. I’ve seen that mind-blowing demo of hot-reload ...
New
bitli
In case this is handy for other people, here is how you can run Elixir on Android: Install https://termux.com/ apt update; apt upgrad...
New
kevinlang
Hey all, With Phoenix 1.6 just around the corner, I figured I’d make a tutorial on how to add Bulma to a new Phoenix 1.6 project. By lev...
New
AstonJ
With a few questions relating to this recently, I wonder if it might help having a thread where we share how we’ve set up Elixir/Erlang/P...
New

Other popular topics Top

josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
yurko
Here are few pieces of (common) Linux knowledge that we use for reasonably small one server apps. We use Ubuntu but this should work for ...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
William
I would like to know that is there any online source for learning Phoenix Framework for building E-Commerce Store? Any advantage on build...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New

We're in Beta

About us Mission Statement