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

Types

The refresher list or function.

The LiveView socket

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

refresher() ::
  [{atom(), (() -> any()) | (socket() -> any())}] | (socket() -> socket())

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

Link to this function

assign_attribute(socket, tuple)

View Source

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
Link to this function

assign_attribute(socket, subscribe, filter \\ :_, refresher)

View Source

Assigns a new attribute to the given socket.

  • socket the LiveView socket where the assigns should be executed on
  • subscribe 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, :_], :_}. Alternatively filter 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)
Link to this function

update_attribute(socket, name)

View Source

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)