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

Logan
Here is an example of a Mix application that utilizes Cowboy to handle websocket connections. If anyone has an idea about making this wor...
New
stryrckt
I’m excited about the new LiveComponents feature in LiveView, but I haven’t seen much written on it, so I decided to write a couple of ar...
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
fmcgeough
pipe into case? I use that fairly frequently…unless I’m misunderstanding what you’re wanting…could be.. its still very early… str = "Hel...
New
sergio
Hey there, we’re going to walk through deploying a Phoenix app to a DigitalOcean droplet, manually - no tools no nothing. Just straight u...
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
eclark
I’ve been working on a phoenix project lately and I wanted to use the latest versions of everything. Webpack 5 had some breaking changes ...
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
mhanberg
Hi! I recently finished adding authentication to my Phoenix API, so I wanted to share what I learned. I haven’t created authentication f...
New
nietaki
Just a quick heads up: There seems to be a bug in Erlang/OTP 21.3, which can cause some errors when making http requests. If you’re using...
New

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42158 114
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement