ngModel getterSetter is called before validity has been checked when allowInvalid is true #15930
Description
I'm submitting a ...
- bug report
- feature request
- other (Please do not submit support requests here (see above))
Current behavior:
I have a custom ng-model
input which uses a getter-setter and allows invalid values:
<custom-input ng-model="value" ng-model-options="{
allowInvalid: true,
getterSetter: true
}"></custom-input>
When the value of the model is changed using $setViewValue()
, the getter-setter is called. Inside the getter-setter, I inspect the ng-model
to see which errors, if any, are present. However, it seems that the validators are not called until after this, so I see a stale result. E.g. if the value has just been changed to something which should be invalid, no errors can be found until e.g. the next digest cycle.
Documentation for $setViewValue()
states "If there are no special ngModelOptions
specified then the staged value is sent directly for processing through the $parsers
pipeline. After this, the $validators
and $asyncValidators
are called and the value is applied to $modelValue
. Finally, the value is set to the expression specified in the ng-model attribute and all the registered change listeners, in the $viewChangeListeners
list are called." In other words, validation should be performed before the getter-setter is called.
I admit that allowInvalid
may constitute a "special ngModelOption
", but it is not called out in later paragraphs, whereas updateOn
and default
are, so I would expect the regular behaviour.
Expected / new behavior:
For my use case I would prefer it if validation is always performed before the getter-setter is called, even if allowInvalid
is true
.
Alternatively (this is not my preferred solution) it would at least be nice to call out this special behaviour in the documentation.
Minimal reproduction of the problem with instructions:
Here. Click the button to see the behaviour. I think the two Booleans should be identical.
Angular version: seen in 1.5.11 but the code in question is still there in 1.6.x
Browser: Chrome 57 on Windows 7 but likely not platform-related
Anything else:
I think the code to be changed is here.