-
Notifications
You must be signed in to change notification settings - Fork 26.2k
fix(forms): ValueAccessor.writeValue(...) sometimes called with null #38140
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
Conversation
|
Hi @N2D4, thanks for creating this PR 👍 I noticed that it's in Draft mode (i.e. it's probably not fully ready for review), but I wanted to share an idea. If I understand correctly the first "writeValue" with the Would that work? (If that works as needed, it should avoid passing configuration params though a few function calls) Thank you. |
Sure, implemented. I also added an integration test (/modified an existing one), so this is now ready for review 👍 |
|
Hi @N2D4, I performed initial review and added the "breaking changes" flag to this PR, since the new behavior is different from the old one (i.e. there us no additional I've also ran a set of tests in Google's codebase (internal-only link) and it looks like the problem is a bit more tricky. I found some additional cases were this change would be breaking. Here is a couple snippets that illustrate the problem: Component's template: Validator (simplified version): The problem is that the Given the fact that the In any case, I think it'd be great to add the above mentioned example as a test case (it should be useful to count the number of times sync/async validator was called) and evaluate whether Please let me know your opinion. Thank you. |
`ValueAccessor.writeValue(...)` is called twice on the very first `ngModel` change if the form has not yet been set up; once by `setUpControl` and once when the value is actually updated. However, because `setUpControl` is called before the value is set, the first call passes `null`. The bug is most common for standalone form controls which are never set up before the first `ngModel` change but may also happen if any other form control is not added to its parent first by calling `NgForm.addControl(...)`. Fix that by optionally skipping the `writeValue(...)` call in `setUpControl` if an optional flag is given. Fixes angular#14988
|
Hi @AndrewKushnir, Sorry for the delay, since this is not going to happen before v11 anyways I ended up re-prioritizing things but I'm back to work on this now. As an open-source intern I don't have access to the internal link, but I could reproduce the error you mentioned. I agree that the validator shouldn't be called there, and added a unit test to make sure it's not. Yes, I believe in the Now that we also skip validators when the form control is created, I took a closer look and decided to rename the flag to There was one test that relied on the old behavior of calling validators synchronously during |
|
Then, any news about merging? |
| * | ||
| * @internal | ||
| */ | ||
| export const INITIAL_CONTROL_VALUE = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not used anywhere anymore.
|
Hi @N2D4 and @AndrewKushnir 😄 I saw this PR as a result of debugging this issue: #43718 The problem I had was due to the fact that If I read this PR correctly, it should avoid the first There could be multiple reasons for that! First, that's how Reactive Forms work, but right now the default value for a FormControl is Second, imho it makes more sense for some controls to be I don't know if this directly affects this PR, but since it would eventually fix an issue from years ago, you never know! What do you think about it? :) |
|
This fix requires some additional design work / research as the current approach is too breaking to land as-is. |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |


Fixes #14988
Fixes @ckelley7's marriage
PR Checklist
Please check if your PR fulfills the following requirements:
(technically no, but no doc changes were needed)
PR Type
What kind of change does this PR introduce?
What is the current behavior?
ValueAccessor.writeValue(...)is called twice on the very firstngModelchange if the form has not yet been set up; once bysetUpControland once when the value is actually updated. However, becausesetUpControlis called before the value is set, the first call passesnull.The bug is most common for standalone form controls which are never set up before the first
ngModelchange but may also happen if any other form control is not added to its parent first by callingNgForm.addControl(...).Issue Number: #14988
What is the new behavior?
Optionally skip the
writeValue(...)call insetUpControlif the value is a special sentinel value indicating it has not yet been initialized.Does this PR introduce a breaking change?
(see below)
Other information