Commands

Commands in Hologram are server-side operations that allow you to:

They are typically used for operations that require server processing, and are always executed asynchronously.

Defining Commands

Commands are defined as functions in your page or component modules using the following syntax:

def command(name, params, server) do
  # Command logic here
end

For example:

def command(:save_user, params, server) do
  case MyApp.Users.create(params) do
    {:ok, user} ->
      put_action(server, :user_saved, user: user)
      
    {:error, changeset} ->
      put_action(server, :validation_failed, errors: changeset.errors)
  end
end

Command Parameters

Commands receive three arguments:

Command Results

Commands must return a %Server{} struct. This struct not only manages server-side state (session and cookies) but also includes instructions for what happens next through functions that can be called on it. These functions are pure - they don't cause any side effects and simply return a new modified %Server{} struct. Since these functions return the modified %Server{} struct, they can be chained together using the pipe operator |>, allowing for a clean and composable way to combine multiple state changes and behaviors.

Within a command, you can:

Trigger a Client Action

Action with the specified name without any additional parameters:

put_action(server, :my_action)

Action with the specified name and additional parameters provided as a keyword list:

put_action(server, :my_action, param_1: value_1, param_2: value_2)

Action with a specified name, target, and parameters using a map for the parameters (in this longhand version, both params and target are optional):

put_action(server, name: :my_action, target: "other_component", params: %{key: value})

Using an %Action{} struct:

put_action(server, %Action{name: :my_action})

Update Session Data (coming soon)

Future versions of Hologram will support managing session data, for example using put_session/3:

put_session(server, :user_id, user.id)

Update Cookies (coming soon)

Future versions of Hologram will support managing browser cookies, for example using put_cookie/3:

put_cookie(server, :remember_token, token)

Navigate to Another Page (coming soon)

Future versions of Hologram will support server-side navigation, for example using put_page/3:

put_page(server, ProductPage, id: product.id)

Triggering Commands

Commands can be triggered using event attributes in templates or from actions.

Template Event Attributes

Trigger a command named :my_command, targeting component with CID "other_component" and passing parameters a and b with values 1 and 2, respectively (both target and params are optional):

<button $click={command: :my_command, target: "other_component", params: %{a: 1, b: 2}}>Click me</button>

From Actions

Commands can also be triggered from actions using put_command/3:

def action(:save_form, params, component) do
  component
  |> put_state(:saving, true)
  |> put_command(:save_user, user: params.user)
end

Command Targets

By default, commands are executed on the component that contains them. If the component is stateless (doesn't have a CID specified), the closest stateful component higher in the hierarchy is used. You can specify a different component for execution using the target parameter:

<button $click={command: :my_command, target: "other_component"}>Click me</button>

Valid targets include: