-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(input): fix false initial 'number' validation error in input[number]... #9193
fix(input): fix false initial 'number' validation error in input[number]... #9193
Conversation
…er] with observed attributes When no value has been set for an input[number] it's viewValue is undefined. This lead to false parse validation errors, when `ctrl.$validate()` was fired before interacting with the element. A typical situation of this happening is when other directives on the same element `$observe()` attribute values. (Such directives are ngRequired, min, max etc.) More specifically, the parser for native HTML5 validation returns undefined when the input is invalid and returns the value unchanged when the input is valid. Thus, when the value itself is undefined, the NgModelController is tricked into believing there is a native validation error. Closes angular#9106
Hm...originally I thought it was related to (I also removed some blank lines in the name of uniformity; I am not sure if it's OK though :D) |
For the fun of it, until this issue gets solved, here is a little addition that solves the problem. |
…er] with observed attributes When no value has been set for an input[number] it's viewValue is undefined. This lead to false 'number' validation errors, when `ctrl.$validate()` was fired before interacting with the element. A typical situation of this happening is when other directives on the same element `$observe()` attribute values. (Such directives are ngRequired, min, max etc.) More specifically, the parser for native HTML5 validation returns either undefined (when the input is invalid) or the parsed value (when the input is valid). Thus, when the value itself is undefined, the NgModelController is tricked into believing that there is a native validation error. Closes angular#9106
Hi, thanks for the PR. However, I'd like to check if this isn't a more general issue that should be solved differently, since (if I follow your explanation in #9106 (comment) correctly) the parser pipeline goes haywire if validate is called with "empty" modelValues. |
@Narretz: My PR solves the number-type problem.
This comes in contrast with the number-type formatter, which allows an originaly undefined viewValue to remain undefined:
|
Just FYI this is likely related to #9044 too, so it also affects selects. Maybe some general solution could be achieved? As it isn't exactly specific to one input type. I'm not sure why we even started treating |
The problem with ngList is indeed similar (although not related to But it is again the combination: So, it is a more generic problem. I am not that confident with all the complexities of the NgModelStuff and all input directives, but to me it doesn't sound horrible to initialize a modelValue/viewValue to a default empty value per input type (if no value is specified). I feel that binding the model to an input is "programatic change" enough to justify setting it to the value that the input's current state/value call for. (I am afraid @caitp will not agree though :)) |
Yeah, this is an interesting question But the deeper issue was that angular should not modify the modelValue when the input / parsed viewValue is empty, that is it should somehow short-circuit after parsing if no modelValue is created. I thought about aborting parsing altogether when the viewValue is empty, but it's possible that a parser transforms an empty value into a value, so that's not gonna work. Invalid parsers returning undefined is obviously the elephant in the room for this approach. |
The main issue is that parsing and validating should be independent, but aren't right now. That said, I am not convinced that "Angular should not modify the modelValue when the input / parsed viewValue is empty". Why shouln't it ? As soon as I bound my model to specific type of input, I make a commitment and expect that my model will have a value reasonable for that type of input. This includes the empty value. I don't agree that a model bound to an empty number input should have the same value as a model bound to an empty data input or to an empty ngList input. I think it is only natural that an empty list will be |
See #9044 (comment) --- the fix for avoiding the parse error when validate() is called with undefined view values has already landed |
I think we might want these tests though anyways, I will refactor the commit a bit and get the tests in |
then again, the tests are sort of variations on existing tests in the tree.. hmm --- I will add one of them anyways |
@caitp: Yes, I've seen you landed a fix for that. I was thinking if it would make sense to merge the tests though, because actually there is only one test for ngRequired. Tell me if you think this is a good idea and if you need me to make a separate commit with just the tests. (Note that since your commit landed, 3 of my tests need a slight modification ( |
There are ngRequired tests for the more general case, not specific to number inputs --- but it's basically verifiably working as expected when we don't treat an unspecified view value as a parse error |
However if you think the entire suite of ngRequired tests are needed for number inputs, we could certainly add another commit with those tests |
@caitp: I added the tests in #9316. I can see there are tests for |
... with observed attributes
When no value has been set for an input[number] it's viewValue is undefined. This lead to false
parse validation errors, when
ctrl.$validate()
was fired before interacting with the element. Atypical situation of this happening is when other directives on the same element
$observe()
attribute values. (Such directives are ngRequired, min, max etc.)
More specifically, the parser for native HTML5 validation returns undefined when the input is
invalid and returns the value unchanged when the input is valid. Thus, when the value itself is
undefined, the NgModelController is tricked into believing there is a native validation error.
Closes #9106