Unified messaging for LiveViews and LiveComponents, to allow for simple decomposition of LiveViews into LiveComponents.
From any LiveView or LiveComponent you can:
send_info(target, message)
or
send_info_after(target, message, time)
which will trigger a handle_info/2
in the target LIveView or LiveComponent:
def handle_info(message, socket) do
....
{:noreply, socket}
end
The "target" here is the ID of the LiveView or LiveComponent available though the @me
assign, e.g.
<.live_component module={MyComponent} id="my_component"
target={@me}
/>
Think of @me
like @myself
but for live messaging.
LiveComponents are a great way to break up large LiveViews into smaller reusable components. But what happens when your LiveComponents get too big? You could break them down into smaller components, but this comes with a couple of issues:
- LiveComponents get coupled to their parent
- LiveComponent message handling is coupled to initialisation
In order for a LiveComponent to communicate to it's parent, it needs to send messages. If it's parent is a LiveView you need send/2
,
but if it's parent is a LiveComponent you need LiveView.send_update/2
. So a component needs to know what it's parent is and handle that variation.
To send a message to a LiveComponent you use LiveView.send_update/2
and this is handled in the update/2
function. Typically update/2
is used to set the assigns for the LiveComponent, so for it to also be the message handling function feels like these concerns have not been properly separated:
def update(%{my_message: message}, socket) do
# handle message
{:ok, socket}
end
def update(assigns, socket) do
# Initialise state
{:ok, socket}
end
LiveMessage solves both these issues by providing a unified way to message LiveViews and LiveComponents that both use handle_info/2
to handle the messages.
The package can be installed by adding live_message
to your list of dependencies in mix.exs
:
def deps do
[
{:live_message, "~> 0.1.12"}
]
end
Next, add the following use
statements to your web file in lib/my_app_web.ex
:
# lib/my_app_web.ex
def live_view do
quote do
# ...
use LiveMessage.LiveView
end
end
def live_component do
quote do
# ...
use LiveMessage.LiveComponent
end
end