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

voltone
The EEF’s Security WG has released the first public draft of the Secure Coding and Deployment Hardening Guidelines for BEAM languages. “...
New
kuon
I have a page with a large state that is loaded from DB, let’s call that “data”. I have a root live view that load “data” on mount and r...
New
crockwave
To integrate dropdown menus in a Phoenix Liveview app, you can use a combination of js, Hooks, CSS and your .leex and .ex code. You can...
New
9mm
So I’m really loving elixir. BY FAR the most excruciating piece of learning a functional language for me is having to “transform” all my ...
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
njwest
In the process of developing a Phx-based multiplayer experience, I found myself with so many browser tabs open with Elixir gaming resourc...
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
f0rest8
Hi everyone, Just wanted to say that the new Self-referencing many to many guide is now up on the official Hex docs (at least I just not...
New
alejandroErik
POST IN CONSTRUCTION Process for compile erlang otp 20 with odbc-unix for Oracle connections on Solaris 11.3 for 64 bits: Introductio...
New
anuragg
We finally have a Mix clustering guide to go with Phoenix deployment with Mix Releases. Deploy an Elixir Cluster with Mix Releases and l...
New

Other popular topics Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
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
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
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

We're in Beta

About us Mission Statement