Lavash (Lavash v0.3.0-rc.0)

Copy Markdown View Source

Reactive state management for Phoenix LiveView.

Lavash is two things in one package:

See the README for a full guide. The minimal DSL example:

defmodule MyAppWeb.ProfileLive do
  use Lavash.LiveView

  state :user_id, :integer, from: :url, required: true
  state :tab, :string, from: :url, default: "overview"
  state :editing, :boolean, default: false

  read :user, MyApp.Accounts.User do
    id state(:user_id)
  end

  actions do
    action :change_tab, [:tab] do
      set :tab, rx(@tab)
    end
  end

  render fn assigns ->
    ~L"""
    <div>...</div>
    """
  end
end

Imperative API

Inside a handler, when the declarative pipeline doesn't fit, use the imperative helpers:

def handle_event("save", %{"product" => params}, socket) do
  socket =
    socket
    |> Lavash.set(:form_data, params)
    |> Lavash.set(:submitting, true)
    |> Lavash.finalize(__MODULE__)

  # derived fields are now recomputed and assigns projected
  {:noreply, socket}
end

Summary

Functions

Gets the full derived state map.

Finalizes state changes by recomputing dirty derived fields and projecting assigns. Call this after using set/3 or update/3 in a handle_event.

Gets a state or derived value from the socket.

Sets a state field value. This is for use in handle_event callbacks when you need imperative control.

Gets the full state map (not including derived).

Updates a state field using a function.

Functions

derived(socket)

Gets the full derived state map.

finalize(socket, module)

Finalizes state changes by recomputing dirty derived fields and projecting assigns. Call this after using set/3 or update/3 in a handle_event.

Examples

def handle_event("save", params, socket) do
  socket =
    socket
    |> Lavash.set(:form_data, params)
    |> Lavash.set(:submitting, true)
    |> Lavash.finalize(__MODULE__)

  # Now derived fields are recomputed and assigns are projected
  {:noreply, socket}
end

get(socket, field)

Gets a state or derived value from the socket.

Examples

changeset = Lavash.get(socket, :changeset)
form_data = Lavash.get(socket, :form_data)

set(socket, field, value)

Sets a state field value. This is for use in handle_event callbacks when you need imperative control.

Note: This does NOT automatically recompute derived fields or project assigns. Call Lavash.finalize/2 after all updates to trigger recomputation.

Examples

socket = Lavash.set(socket, :form_data, params)
socket = Lavash.set(socket, :submitting, true)
socket = Lavash.finalize(socket, __MODULE__)

state(socket)

Gets the full state map (not including derived).

update(socket, field, fun)

Updates a state field using a function.

Examples

socket = Lavash.update(socket, :count, &(&1 + 1))