sreyansjain

sreyansjain

Does Hologram support two way data binding?

I have a state in Hologram lets say %{age: “40”}

I have an input like so

<input type="text" name="age" value={@age} />

I want to bind the value of input to the age.

I can do this

<input type="text" name="age" value={@age} $change="update_age" />

And then I can do

def action(:update_age, %{event: %{value: age}}, component) do
    put_state(component, age: age)
end

Is there another way to do this?
Does/will Hologram support two way data binding?

First 10 of 32 Posts Switch mode

bartblast

bartblast

Creator of Hologram

A post was split to a new topic: String.to_integer and Integer.parse! don’t work

bartblast

bartblast

Creator of Hologram

There’s an important limitation to be aware of in v0.5.0. The issue you’re experiencing is that text-based input DOM elements are stateful and prioritize user-typed input over value attribute updates (this is a general DOM/HTML behavior, not specific to Hologram).

This is actually the same problem that Phoenix LiveView users encounter, as discussed in this Elixir Forum thread: HTML <input value doesn't reflect update in assign. When a user has already typed anything into an input field, you can’t change the input value through the value attribute programmatically - the browser maintains its own internal state.

Good news though! This limitation is being addressed in v0.6.0, which is already implemented on the dev branch. You can try it out by updating your mix.exs:

{:hologram, git: "https://github.com/bartblast/hologram.git", ref: "84867a2869fa4f58a01e3849eba3b7525773350d"}

With this version, your current code will essentially work like true two-way data binding (no code changes needed in your example). The framework will handle the DOM state management properly, so when you update the component state through your $change event handler, the input value will update correctly.

Eventually, I’m planning to add some sugar syntax for this similar to how Vue or Svelte handle it, but for now, the manual approach (like in your example) works well.

bartblast

bartblast

Creator of Hologram

@sreyansjain I need to correct my previous advice about using the dev branch.

I shouldn’t have instructed you to use the head of the dev branch (branch: "dev") because there’s currently some incomplete work on CSRF protection that will probably prevent your app from sending commands properly. And generally you shouldn’t rely on the head of the dev branch either. The framework is actively being developed, so sometimes the dev branch can be in a transitional state.

Instead, use the last “green” commit from the dev branch:

{:hologram, git: "https://github.com/bartblast/hologram.git", ref: "84867a2869fa4f58a01e3849eba3b7525773350d"}

This commit has the two-way data binding improvements I mentioned, but without the breaking CSRF changes that are still in progress. Your original code example should work correctly with this specific commit.

Sorry for the confusion!

PS: original post amended…

garrison

garrison

The code in the OP is quite explicitly a one-way binding. Two-way binding is very bad and should be avoided. Probably one of React’s greatest contributions was killing it.

Unfortunately this problem is essentially impossible to fix with LiveView because it turns into a consistency problem. A controlled input in LiveView would have too much latency.

This is actually a pretty interesting advantage for Hologram because you could use exactly the same logic to validate/control the input on the client and server, which would be pretty cool if you get the API right.

bartblast

bartblast

Creator of Hologram

Fair point on the terminology - I made a mental shortcut and incorrectly called it “two-way binding” when what I actually implemented is controlled components where the input value always reflects the current state AND user input updates the state through explicit handlers - which is what the OP wants to achieve (I assume), just with proper unidirectional data flow (solving the DOM synchronization problem that LiveView has).

Could you recommend better terminology for this? I’m thinking along the lines of “controlled input components” or “reactive form controls,” but I want to make sure users understand what this achieves functionally. Since we’re in a functional language context where there’s no true “binding” per se, what would best communicate that inputs now properly reflect state changes? I used “two-way binding” as shorthand for what users typically want - inputs that stay synchronized with state - but I realize that term has specific technical implications I should have avoided. (I should probably update the thread title too.)

And yes, you’ve hit on exactly the key advantage here: because Hologram runs client-side and is close to the DOM, it can solve consistency problems that are fundamentally unsolvable in LiveView due to the server-client latency gap. The ability to run the same validation/control logic on both client and server is indeed a significant architectural benefit :slight_smile:

garrison

garrison

One-way (unidirectional) data flow is good! Two-way binding is just literally the opposite of that. I can’t speak to why the OP brought it up, but the two-way binding approach (see e.g. OG Angular) was very bad and React’s one-way dataflow obsoleted it.

The code in the OP is indeed one-way, and it sounds like Hologram encourages the React approach, which is good.

They are generally called controlled components in React, but that refers to a specific pattern: letting React own the state instead of keeping state in the DOM. The reason this terminology exists is to promote that pattern, as in the past many thought the idea of putting everything in JS was ridiculous and it took time for people to realize that was a good idea (“rethinking best practices” indeed).

Nowadays React is the default many web devs are trained on so I’m not sure if you really need to explain this stuff or not. You’ll probably have to work with feedback from people learning Hologram down the road for stuff like this, one person (me) is not representative at all.

As the author of the framework you are thinking in implementation details. Most developers have no idea how React (or Hologram) works, they just know that when they set value={myValue} the thing on the page updates. That abstraction is good enough for them, there is no need to cause confusion by going any deeper.

jam

jam

Fwiw, “two-way binding” for me is associated with svelte’s bind: which imo is nice and doesn’t present any issues particularly in the scenario discussed in this thread. If you use it to communicate up to a parent component, I could see how that could get hairy if you’re not careful.

These seem less clear imo

Agreed

sreyansjain

sreyansjain OP

The code is indeed one way data binding.
I wanted to know is there another approach or a shorthand to sync the input value with the state or more specifically update the state automatically on input value changes.

Liveview cannot have 2 way bindings because of the round trip, but in case of hologram there is no round trip required for achieving this.
I hear JS frameworks these days are using signals and there is already a proposal for implementing the same in the browsers.

Updating an input value can cause the signal to change which for all practical purposes is as good as two way reactive data bindings.

I don’t have much experience with front end tech, I am mostly used to server driven development with liveview or alike. So my frontend knowledge might be a bit off.

bartblast

bartblast

Creator of Hologram

Form handling is such a fundamental feature that I think we need to nail down clear, consistent terminology for how Hologram approaches it. It’s one of the most common client-side use cases and probably what trips up LiveView users the most - as discussed in this BlueSky thread. I’m planning a dedicated “Forms” page for the website since good and consistent docs are crucial for good DX.

I totally agree that most developers won’t care about implementation details and just want value={@my_value} to work. That abstraction is perfect for them. However, some developers will want to compare Hologram with other frameworks, and having consistent naming for this pattern will be helpful in discussions and documentation.

Based on the feedback here, I’ll definitely avoid “two-way binding” or “bidirectional binding” since these don’t accurately describe what Hologram does and have historical baggage.

I’m considering these alternatives:

  • “Controlled Inputs” - familiar to React developers
  • “State-Synchronized Inputs” - descriptive for newcomers
  • “Input Synchronization” - focuses on the key benefit

(or “Form Elements” instead of “Inputs”)

The core concept is that Hologram maintains unidirectional data flow while solving the DOM synchronization problem that LiveView can’t address.

What do you think would be the clearest terminology? I want to get this right since it’ll be used throughout the documentation and forum discussions.

LostKobrakai

LostKobrakai

This is a topic full of footguns though. The value attribute of inputs in html is used to set the default value of that input, the value reverted to e.g. when you reset a form (<input type="reset">). The value of the input itself is the input.value property of the dom node (vs. input.getAttribute("value")). You can ignore that distinction – LV by my understanding does so – but it’ll mean you might break expectations for people who understand and use that distinction.

Where Next?

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
jonnycharles
I’m in search of an Elixir library that offers PDF generation capabilities similar to Ruby’s Prawn. While there have been discussions abo...
New
spammy
I’m looking to build a personal workflow to quickly deploy web applications written in elixir/phoenix, for local consumption (ie not on t...
New
silverdr
Using Phoenix.LiveView.TagEngine as an EEx.Engine is deprecated! To compile HEEx, use Phoenix.LiveView.TagEngine.compile/2 instead. Sta...
New
dli
Before I dive in myself, did anyone successfully sprinkle Hologram into their existing LiveView app? Looking for hints regarding: Addi...
New
bottlenecked
Hi all, I wanted to ask how the community is dealing with post-release steps. Today we have Ecto migrations, which make sure that the db...
New
michallepicki
I am using Oban and occasionally, shortly after a deployment, a handful of jobs can fail because of dependency on other parts of the syst...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
ausimian
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
type1fool
I just stumbled on a newly redesigned elixir-lang.org. :tada: It looks like @Software_Mansion did the work, and I think it is generally a...
New
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New

We're in Beta

About us Mission Statement