(Test) Liveview input forms are not controlled by the server state when input is in focus

In react, there is the concept of a “controlled component”. Typically, input elements and the like manage their own state and respond to user input. However, sometimes it is convenient to let react store the state of the input, so it can serve as the single source of truth.

I’ve been experiencing difficulties with liveview where it seems like the input is not controlled by the server state, despite the state changing.

Contrived example:

def mount(_params, _session, socket) do
    {:ok,
     assign(socket, %{
       value: ""
     })}
  end

  def handle_event("set_value", %{"key" => "ArrowUp"}, socket) do
    rand = :rand.uniform(1_000_000)
    {:noreply, assign(socket, value: rand)}
  end

  def handle_event("set_value", _params, socket) do
    {:noreply, socket}
  end
<div phx-window-keyup="set_value">
  <input type="text" value={@value} />
</div>

The value of the input should be set the match the value of the state of the liveview. Anytime an ArrowUp event occurs, it should select a random number, and set the value of the input to that number. This works fine when the input is not in focus, and the value in that input element is updated accordingly.

The confusing part occurs when you click into the input such that it is in a focused state. Now, if you try to press up on the arrow pad, the handle_event call does fire and does update the state, but the input value does not follow along. You can type whatever you want – in react it would not let you type anything, since the react state is the single source of truth and it would keep insisting that the value of the input be the random number.

1 Like

Testing with Erlang logo on page:

Screenshot 2021-07-30 at 16.06.16

1 Like

Macros are just functions that take AST as parameters and are expected to return AST. Generally AST is created using quote blocks. But you can quote any code whether in a macro of not. So you to get the AST of the code you show, it would be a matter of:

defmodule TestModule do
  defmacro test_macro(param1, param2, param3) do
    quote do
      param1 + param2 + unqoute(param3)
    end
  end
end

Note that:

  1. In this case param1 and param2 in the quote block have nothing to do with the parameters passed to the macro. They are variable references that would need to be referenceable in the calling site.
  2. unquote will dereference the parameter param3. If your intent was to get the AST for unquote(param3) then change the quote do block to be quote unquote: false do
1 Like