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

Input value set in component mounted hook can lead to stale data #65

Open
mattheyan opened this issue Jun 20, 2022 · 3 comments
Open

Input value set in component mounted hook can lead to stale data #65

mattheyan opened this issue Jun 20, 2022 · 3 comments

Comments

@mattheyan
Copy link

mattheyan commented Jun 20, 2022

Describe the bug
Apologies in advance for the complicated scenario. If a masked input's value is set after the directive binds, the oldValue property won't be established when the directive binds, which can cause the input's value to be re-used when the component updates due to the underlying data that the input is binding to being updated. I know that's probably hard to follow, so hopefully a more long-winded explanation will help.

The oldValue property is set initially due to a call to updateValue from the bind method of the directive. If the input doesn't have a value yet then oldValue won't be set (and will remain undefined). If a component uses the mounted hook to set the input value programmatically (ex: element's input component), this will happen before the directive is inserted, but after bind, so it won't cause oldValue to be established. If the underlying data changes, the component will update, which will call the directive's update method. Since the oldValue was never established this will cause it to mask the input's value (which has not yet been updated to reflect the change to the data) and raise an input event. It seems like this depends on the exact configuration of components, but the input event may cause the component to capture the value of the input at that time rather than updating to use the new value from the underlying data.

To Reproduce
I have tried to reproduce the problem in a codepen, but haven't had luck so far. Unfortunately I can't currently send a demo link in the app where the issue was discovered.
Steps to reproduce the behavior:

  1. Use an element input component to bind to some underlying string data, ex: "(800) 123-4567"
  2. Attach the facade directive with a mask, ex: phone number. In my case the directive is attached to an ancestor of the input, but I'm not sure if that matters or not.
  3. Update the underlying data, ex: to blank string
  4. The input in the DOM retains the original value, ex: "(800) 123-4567"

Expected behavior
The element in the DOM should be updated to reflect the new value in the underlying data / object.

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Chrome (any)
  • Version: 102.0.5005.115

Additional context
I know you'd like to have a repro, and if I'm able to I will send one. But hopefully its at least possible to see in the code how this could be a problem. In terms of a fix, if oldValue is established when the component mounts (and "inserted" is called), then the input event won't be raised when the component update occurs, which avoids the problem in my scenario. Please let me know if you have any thoughts on this, or better ideas for how to fix it.

Thanks!
- Bryan

@mattheyan
Copy link
Author

I was able to repro in a test at least, which I will attempt to push to a fork tomorrow.

@mattheyan
Copy link
Author

Here's the test where I was able to reproduce the problem. I tried to get it as close as I could to what was I seeing in the app.

@RonaldJerez
Copy link
Owner

Hey @mattheyan, thanks for the report. I’ll take a look in detail once I get a chance.

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

No branches or pull requests

2 participants