Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Value of the input is not updated if the it was previously updated with the same string (regression starting 3.22) #19341

Closed
andreyfel opened this issue Jan 18, 2021 · 10 comments · Fixed by glimmerjs/glimmer-vm#1268 or #19412
Milestone

Comments

@andreyfel
Copy link
Contributor

🐞 Describe the Bug

Let's say you have a native input with a value bound: .

  1. this.myValue is a tracked property. It gets updated to foo, the input gets foo as a value.
  2. Then the user interacts something different into the input let's say bar.
  3. Something triggers update of the myValue to foo.
  4. I expect the input value to be updated to foo, but it remains bar.

🔬 Minimal Reproduction

Here is an integration test which reproduces the issue:
It passes for 3.21.3 and fails in 3.22.0. It fails in 3.24.1 as well.

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { hbs } from 'ember-cli-htmlbars';
import { blur, fillIn, render } from '@ember/test-helpers';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';

module('Integration | Component | input value', function(hooks) {
  setupRenderingTest(hooks);

  class MyModel {
    @tracked value = '';

    @action
    onBlur() {
      this.value = 'foo';
    }
  }

  async function testChange(assert, input) {
    await fillIn('.my-input', input);
    await blur('.my-input');

    assert.dom('.my-input').hasValue(`foo`);
  }

  test('it renders', async function(assert) {
    this.model = new MyModel();

    await render(hbs`
      <input
        {{on "blur" this.model.onBlur}}
        class="my-input"
        value={{this.model.value}}
      />
    `);

    await testChange(assert, 'bar');
    await testChange(assert, 'baz');
  });
});

➕ Additional Context

The use case for that is an input which is used as a parser, user inputs something hits TAB, the parser interprets the input and updates the string. If the results of 2 consecutive parses are the same then the user ends up with the string he filled in, not the parsed one.

@andreyfel
Copy link
Contributor Author

@pzuraq any ideas on this one?

@pzuraq
Copy link
Contributor

pzuraq commented Feb 1, 2021

I haven't had time to start digging into this one unfortunately. Will update when I do have a chance, hopefully in the next few weeks.

@andreyfel
Copy link
Contributor Author

Tested it with ember-source 3.25.1, it is still an issue there.

@raido
Copy link
Contributor

raido commented Feb 12, 2021

I've hit this scenario as well I think.

I am coming from Ember v3.20 -> v3.24.

Use case seems similar of author's. I have tracked object, which follows immutability pattern like so:

function someStateUpdater(updates) {
  this.someState = assign({}, this.someState, updates);
}

And in template I have:

<input value={{this.someState.someInputValueProp}} />

Previously whenever someState object would get re-assigned, UI would nicely update and keep input field in sync. Example clearing the input value when assigning someInputValueProp = null, example: someStateUpdater({ someInputValueProp: null }).

This however no longer holds true.

User story example:

  • Initial state: someInputValueProp = null
  • Input is focused, user types into the field but someInputValueProp is updated after some other decision point, so for period of time someInputValueProp is not in sync with real input value.
  • In case setting someInputValueProp never occurs, for example due to "user cancelling action", then previously reassigning state object someStateUpdater({ someInputValueProp: null}) would reset input field to be empty as well, but with Ember 3.2x+ it no longer does it.

Edit 1:

I found one other test case I have following immutability pattern and it fails to trigger {{did-update (fn this.someStateChanged @passedInObj)}} although in test clearly this.set("passedInObject", { ...initialState, someNewProps }); is called after initial rendering.

@pzuraq
Copy link
Contributor

pzuraq commented Feb 12, 2021

@raido can you add a failing test like @andreyfel's that demonstrates your variant of the issue? It would be helpful to make sure I have the details right when debugging

@raido
Copy link
Contributor

raido commented Feb 12, 2021

@pzuraq This should be as close to my problem as I could get it - raido/tracked-failures@f460f34

Once you switch ember-source to v3.20.0 tests will pass.

@pzuraq
Copy link
Contributor

pzuraq commented Feb 12, 2021

@raido I think your issue may be related to #19403, but I'm unsure. I had enough time to dig into this issue today, but I don't think I'll have time to get to that one just yet, maybe next week.

@raido
Copy link
Contributor

raido commented Feb 13, 2021

Might be. I'll try to verify. It seems my reproduction has 2 different issues, one related to this issue about input.value and other for did-update behaviour.

@raido
Copy link
Contributor

raido commented Feb 13, 2021

@pzuraq I left comment on reproduction to avoid missing context around discussion - raido/tracked-failures@f460f34#commitcomment-47078125

@rwjblue
Copy link
Member

rwjblue commented Feb 16, 2021

Reopening until the rendering engine is updated here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants