svelte: View is not updated when object with same initial value for property is assigned

Describe the bug

  • Use an object property value as the value of an input, e.g. <input value={object[key]} />

  • Type something in the input, replacing what is displayed

  • Replace object with another object that has the same initial value for object[key]

The view does not update.

To Reproduce

https://svelte.dev/repl/2ce831b444cd4de686e0527f8837858b?version=3.7.1

Expected behavior

The view should be invalidated and subsequently updated when the source object is changed.

Information about your Svelte project:

  • Latest Chrome & Firefox

  • Win10 64

  • Svelte 3.7.1

  • Rollup

Severity

Super honesty hat on: personally it’s a blocking issue for me as I’ve not found a workaround yet (it just occurred to me that maybe I could replace the object with a “dummy” object inside a reactive procedural block, before switching to the desired object?).

However, there are currently no users so no angry mobs shall form because of this.

Thanks!

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 25 (5 by maintainers)

Most upvoted comments

If we come back to the original post, answer is no, that is NOT a bug. One way binding to field in which the user can type can never be “correct” anyway. Suppose the user is busy typing in the field, while an async request finishes and changes the svelte value, th eDOM will “suddnly” be changed while the user it typing. So what? Is that correct? Yes and no, that just the oddity of one way binding to editable fields.

@thejohnfreeman Your point about the chrome inspector is very good.

Looking back some days later that I see the same behavior in Angular as we are all discussing herein Svelte, I think I arrive at approximately the same conclusion:

Unexpected things happen if you do a one way binding to a property/attribute which may change on its own (from user input etc.)… yet the current behavior is demonstrably good enough. This rough edge has not stopped Angular from accumulating a vast user base, and likely won’t stop Svelte from doing so either.

Going further though, it would be great to see “a one way binding is meant for immutable attributes” (also include properties) codified into Svelte. Emit a warning or error if used this way. This would reduce time spent learning and working issues whenever this usage comes up. There is no obviously “right” answer to what Svelte or Angular should do with such a request from the developer. There are problems with any proposed timing of how often the library should monitor whether the targeted value has changed, or if/when it should be set again.

Suppose the user is busy typing in the field, while an async request finishes and changes the svelte value, th eDOM will “suddnly” be changed while the user it typing. So what? Is that correct?

Yes, it’s absolutely correct. I don’t find this example compelling. If you intend to load data at an unknown time, make itdisabled until the data loads if you don’t want the user to be typing stuff at the same time.

It’s on you for having an async function that updates values at a random time while also allowing the user to update values. You have a race condition by design. The oddity you’re referring to is a part of your design in this example. Not very convincing.

__

One-way binding already re-binds when you change the data source, erasing any user input. The arguments being made against this being a bug also apply to the existing behavior, which… exists already in Svelte. Svelte already erases user input if you change the one-way bound data source. So I don’t understand why everyone is debating whether it should do this, when it already does.

The reason this issue is a bug is re-binding does not occur in 1 case only: when the new value after re-binding is the same as the previous one. The general behavior is already established by Svelte, and this is simply a corner case. In all other cases, Svelte does realize the data was changed and triggers an update, erasing anything the user wrote. But if the new value is expected by Svelte to be the same as the old one, no invalidation occurs, an optimization which misses the corner case described in this issue.

I know, it’s not very beautiful code, but it will work good in all cases: https://svelte.dev/repl/2324540ecd874f39b240a71789fd8b17?version=3.7.1

Idea is that on key value change, #each block will be re rendered, this is documented.