mcgingras

mcgingras

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.

Marked As Solved

mcrumm

mcrumm

Phoenix Core Team

Hi @mcgingras – this behaviour is documented in the Javascript client specifics section of the LiveView Form bindings guide:

The JavaScript client is always the source of truth for current input values. For any given input with focus, LiveView will never overwrite the input’s current value, even if it deviates from the server’s rendered updates.

Also Liked

mcgingras

mcgingras

I managed to resolve the issue by using AlpineJS to manage the client state. I passed the LV state to Alpine so its duplicated there. Changes to the LV app state propagate to Alpine, and since Alpine works at the level of the Javascript client it is now working as expecting.

I don’t love the idea of having to duplicate my state in both LV and Alpine… but, its working. :slight_smile:

Thanks

Where Next?

Popular in Questions Top

nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

We're in Beta

About us Mission Statement