Search documentation of mob

# Mob.Event.Address (mob v0.6.18)

Copy Markdown View Source

Canonical address for an event in the Mob view tree.

An address identifies where a widget lives (`screen` and `component_path`) and what fired (`widget`, `id`, `instance`). It also carries `render_id` so handlers can detect events from prior render generations.

See `guides/event_model.md` for the full event model.

## Example

    %Mob.Event.Address{
      screen:         MyApp.CheckoutScreen,
      component_path: [:checkout_form],
      widget:         :button,
      id:             :submit,
      instance:       nil,
      render_id:      42
    }

## Summary

### Types

id()

Anything pattern-matchable that survives serialisation. Atoms are best for compile-time-known IDs; binaries for data-derived ones (DB IDs, UUIDs); integers/tuples for indices and compound keys.

t()

### Functions

current?(address, current_render_id)

True if `addr.render_id` matches `current_render_id`.

new(opts)

Build an address. `screen`, `widget`, and `id` are required. The rest take reasonable defaults.

same_widget?(a, b)

True if the address points to the same logical widget as `other`. Ignores `render_id` — useful for "is this another tap on the same button?" checks.

to_string(a)

Format an address as a short, human-readable string for logs.

validate_id(id)

Validate that `id` is one of the supported types. Returns `:ok` or `{:error, reason}`.

with_render_id(addr, render_id)

Bump the render id on an address (e.g. when re-registering a widget after a render). Returns a new address; original is unchanged.

## Types

# id()

    @type id() :: atom() | binary() | integer() | float() | tuple() | map() | list()

Anything pattern-matchable that survives serialisation. Atoms are best for compile-time-known IDs; binaries for data-derived ones (DB IDs, UUIDs); integers/tuples for indices and compound keys.

Floats, maps, and lists are technically allowed but discouraged: floats have fuzzy equality, maps and lists are heavy to hash on every event.

Pids, refs, and funs are explicitly forbidden — they don't survive serialisation and can't be the basis of a stable address across re-renders.

# t()

    @type t() :: %Mob.Event.Address{
      component_path: [id()],
      id: id(),
      instance: id() | nil,
      render_id: pos_integer(),
      screen: atom() | pid(),
      widget: atom()
    }

## Functions

# current?(address, current_render_id)

    @spec current?(t(), pos_integer()) :: boolean()

True if `addr.render_id` matches `current_render_id`.

Use to detect stale events arriving after a re-render.

# new(opts)

    @spec new(keyword()) :: t()

Build an address. `screen`, `widget`, and `id` are required. The rest take reasonable defaults.

    iex> Mob.Event.Address.new(screen: MyScreen, widget: :button, id: :save)
    %Mob.Event.Address{screen: MyScreen, widget: :button, id: :save, component_path: [], instance: nil, render_id: 1}

    iex> Mob.Event.Address.new(screen: MyScreen, widget: :list, id: :contacts, instance: 47, render_id: 12)
    %Mob.Event.Address{screen: MyScreen, widget: :list, id: :contacts, instance: 47, component_path: [], render_id: 12}

# same_widget?(a, b)

    @spec same_widget?(t(), t()) :: boolean()

True if the address points to the same logical widget as `other`. Ignores `render_id` — useful for "is this another tap on the same button?" checks.

# to_string(a)

    @spec to_string(t()) :: binary()

Format an address as a short, human-readable string for logs.

    iex> Mob.Event.Address.to_string(%Mob.Event.Address{screen: MyScreen, widget: :button, id: :save})
    "MyScreen→button#save"

    iex> Mob.Event.Address.to_string(%Mob.Event.Address{screen: MyScreen, component_path: [:form], widget: :text_field, id: :email})
    "MyScreen/form→text_field#email"

    iex> Mob.Event.Address.to_string(%Mob.Event.Address{screen: MyScreen, widget: :list, id: :contacts, instance: 47})
    "MyScreen→list#contacts[47]"

# validate_id(id)

    @spec validate_id(term()) :: :ok | {:error, atom()}

Validate that `id` is one of the supported types. Returns `:ok` or `{:error, reason}`.

Used by `Mob.Renderer` and `Mob.Event` to fail fast when an obviously-bad ID is passed (e.g. a pid, a function, or an undefined value).

    iex> Mob.Event.Address.validate_id(:save)
    :ok

    iex> Mob.Event.Address.validate_id("contact:42")
    :ok

    iex> Mob.Event.Address.validate_id(42)
    :ok

    iex> Mob.Event.Address.validate_id(self())
    {:error, :pid_not_allowed}

    iex> Mob.Event.Address.validate_id(nil)
    {:error, :nil_not_allowed}

# with_render_id(addr, render_id)

    @spec with_render_id(t(), pos_integer()) :: t()

Bump the render id on an address (e.g. when re-registering a widget after a render). Returns a new address; original is unchanged.