Is send_update
capable of sending messages between separate live view instances, or only between child components of parent live view? The docs are a bit ambiguous on this point, and I can’t seem to get it working for the former use case.
The docs say:
Asynchronously updates a component with new assigns.
So, it appears related to LiveComponent and not other LiveViews. And looking at the code bears that out (since it is sending a message to self()
). But I do think that the docs could be a bit more explicit about it, and specifically that it only affects LiveComponents within the current LiveView.
You can use Phoenix PubSub to send updates to other processes, at least is what I am doing, but I am a beginner in Elixir and Live View.
From the docs:
iex> alias Phoenix.PubSub
iex> PubSub.subscribe :my_pubsub, "user:123"
:ok
iex> Process.info(self(), :messages)
{:messages, []}
iex> PubSub.broadcast :my_pubsub, "user:123", {:user_update, %{id: 123, name: "Shane"}}
:ok
iex> Process.info(self(), :messages)
{:messages, [{:user_update, %{id: 123, name: "Shane"}}]}
Good catch! A PR would be very appreciated too! If you would prefer us to do it, then let me know and I can totally do it, I don’t want to steal your thunder.
I’ll gladly take a stab at it
Indeed the PubSub included in Phoenix itself was basically a drop in solution. It was trivial to get it working in the desired way.
In the ‘helper’ component (a search form):
def handle_event("search", %{"query" => query}, socket) do
Phoenix.PubSub.broadcast(MyApp.PubSub, "main-component", {:search, query})
{:noreply, socket}
end
In “main component” (a list I want to filter):
def mount(_params, _session, socket) do
...
if connected?(socket) do
Phoenix.PubSub.subscribe(MyApp.PubSub, "main-component")
end
{:ok, socket}
end
def handle_info({:search, query}, socket) do
socket = socket
|> assign(:search, query)
{:noreply, socket}
end
And bam, main component knows about this state. Very impressive!
In case anyone tries to use this pattern, I should point out that the string “main-component” is global to the entire application, so be sure to append whatever info necessary to make it as unique as intended.
FYI, this resulted in a PR to update the docs for Phoenix.LiveView.send_update/2
that has been merged: