LiveAttribute (LiveAttribute v1.0.0) View Source
LiveAttribute makes binding updateable values easier. To use it add it to your LiveView using use LiveAttribute
and then use the function assign_attribute(socket, subscribe_callback, property_callbacks)
to register attributes.
The attributes will listen to all incoming events and update their assigns of your LiveView automatically, saving
you the hassle of implementing independent handle_info()
and update_...()
calls.
Example using LiveAttribute
defmodule UserLive do
use Phoenix.LiveView
use LiveAttribute
def mount(_params, _session, socket) do
{:ok, assign_attribute(socket, &Accounts.subscribe/0, users: &Accounts.list_users/0)}
end
end
Same Example before LiveAttribute
defmodule UserLive do
use Phoenix.LiveView
def mount(_params, _session, socket) do
if connected?(socket), do: Accounts.subscribe()
{:ok, update_users(socket)}
end
defp update_users(socket) do
users = Accounts.list_users()
assign(socket, users: users)
end
def handle_info({Accounts, [:user, _], _}, socket) do
{:noreply, update_users(socket)}
end
end
Reusing attribute definitions
Once you find yourself using the same attribute definition on multiple LiveView you can wrap them into a helper function and reuse accross your app.
defmodule Accounts do
def attribute() do
{&subscribe/0, users: &list_users/0)}
end
...
end
defmodule UserLive do
use Phoenix.LiveView
use LiveAttribute
def mount(_params, _session, socket) do
{:ok, assign_attribute(socket, Accounts.attribute())}
end
...
end
Link to this section Summary
Functions
Tuple version of assign_attribute to easily reuse attribute definitions
Assigns a new attribute to the given socket.
Allows force updating an attribute. This is useful for example when the update chain of the attribute depends on another socket.assign that is not subscribed to.
Link to this section Types
Specs
The refresher list or function.
Should preferably be a list of {key, callback}
pairs to load the new attribute values.
The callback
thereby can have optionally one argument to read context from the socket.
Alternatively the refresher can be a single argument function instead of a list. In this
case the function is applied to the socket and thus the user has to ensure that
needed assign()
calls are made manually.
Examples
assign_attribute(socket, &Accounts.subscribe(),
users: &Accounts.list_all/0,
admins: &Accounts.list_admins/0
)
assign_attribute(socket, &Accounts.subscribe(),
users: Accounts.list_all(),
admins: fn socket -> Enum.filter(socket.assigns.users, fn user -> user.is_admin end) end
)
iex> assign_attribute(socket, &Accounts.subscribe(), fn socket ->
users = Accounts.list_all(),
admins = Enum.filter(users, fn user -> user.is_admin end)
assign(socket, users: users, admins: admins)
end)
Specs
socket() :: map()
The LiveView socket
Link to this section Functions
Tuple version of assign_attribute to easily reuse attribute definitions
Example
defmodule Repo do
def accounts_attribute(), do: {&subscribe/0, users: &list_users/0)}
...
end
defmodule UserLive do
use Phoenix.LiveView
use LiveAttribute
def mount(_params, _session, socket) do
{:ok, assign_attribute(socket, Repo.accounts_attribute())}
end
...
end
Assigns a new attribute to the given socket.
socket
the LiveView socket where the assigns should be executed onsubscribe
the subscribe callback to start the subscription e.g.&Users.subscribe/0
filter
an optional filter if you don't want to update on each event. The filter can either be an expression using:_
as wildcard parameter such as{Accounts, [:user, :_], :_}
. Alternativelyfilter
can be a function with one parameter Note LiveAttribute is issuing each subscribe call in an isolated helper process, so you only need to add filters to reduce the scope of a single subscription.refresher
the function callback to load the new values after a subscription event has fired.
Example
iex> socket = assign_attribute(socket, &Users.subscribe/0, users: &Users.list_all/0)
Allows force updating an attribute. This is useful for example when the update chain of the attribute depends on another socket.assign that is not subscribed to.
Example
iex> socket = update_attribute(socket, :users)