model.ts is currently extremely large. This is the first step in an attempt to refactor it to be more easily navigable and reviewable. This commit breaks up `model.ts` into the following new files:
* `model/abstract_model.ts`: The remainder of the model, including the `AbstractControl` base class and helper functions which are used throughout.
* `model/form_control.ts`: `FormControl`, `FormControlOptions`, and helpers, plus the constructor and untyped friends.
* `model/form_array.ts`: `FormArray` and untyped friends.
* `model/form_group.ts`: `FormGroup` and untyped friends.
This first phase is a purely mechanical code move. There is no new code at all, and no interfaces have been separated.
PR Close#45217
Currently, there is a freestanding `getRawValue` function which examines the type of the control. This is an issue for refactoring `model.ts` because it creates unnecessary dependencies between the `AbstractControl` classes. It is cleaner to simply add this method to the model hierarchy and call it directly, and will ease upcoming refactoring.
PR Close#45200
Currently, there is a freestanding `getRawValue` function which examines the type of the control. This is an issue for refactoring `model.ts` because it creates unnecessary dependencies between the `AbstractControl` classes. It is cleaner to simply add this method to the model hierarchy and call it directly, and will ease upcoming refactoring.
PR Close#45200
We had previously introduced an `AnyForUntypedForms` type alias. However, given our updated migration plan, we actually want to use aliases for the model classes themselves. This commit introduces these aliases, and adds them to the public API. It must be merged before the types, in order to migrate google3.
PR Close#45205
When an `NgModel` is created within a `form`, it receives an `NgControl` based on its `name`, but
the control doesn't get swapped out if the name changes. This can lead to problems if the `NgModel`
is part of an `ngFor`, because the name can change based on its position in the list and a new
control can be defined with the same name, leading us to having multiple directives pointing to
the same control. For example, if we start off with a list like :
```
[0, 1, 2]; -> [NgModel(0), NgModel(1), NgModel(2)]
```
Then we remove the second item:
```
[0, 2]; -> [NgModel(0), NgModel(2)]
```
And finally, if we decide to add an item to the end of the list, we'll already have a control for
index 2, causing the list to look like:
```
[0, 2, 3]; -> [NgModel(0), NgModel(2), NgModel(2)]
```
These changes fix the issue by removing the old control when the `name` of the directive changes.
Fixes#38465.
Fixes#37920.
PR Close#40459
This commit updates the `PatternValidator` class to inherit `AbstractValidatorDirective` to make it conistent with other validators.
Closes angular#42267
PR Close#44887
BREAKING CHANGE: Forms [email] input coercion
Forms [email] input value will be considered as true if it is defined with any value rather
than false and 'false'.
PR Close#42803
Form required validator should not reject objects that contain a length attribute set to zero.
Fixes#30718.
Co-authored-by: Dylan Hunn <dylhunn@gmail.com>
BREAKING CHANGE: objects with a length key set to zero will no longer validate as empty.
This is technically a breaking change, since objects with a key `length` and value `0` will no longer validate as empty. This is a very minor change, and any reliance on this behavior is probably a bug anyway.
PR Close#33729
This implementation change was originally proposed as part of Typed Forms, and will have major consequences for that project as described in the design doc. Submitting it separately will greatly simplify the risk of landing Typed Forms. This change should have no visible impact on normal users of FormControl.
See the Typed Forms design doc here: https://docs.google.com/document/d/1cWuBE-oo5WLtwkLFxbNTiaVQGNk8ipgbekZcKBeyxxo.
PR Close#44316
PR Close#44806
Currently, `ngModel` calls` setValue` after the `resolvedPromise` is resolved.
The promise is resolved _after_ the child template executes. The change detection
is run but `OnPush` views are not updated because they are not marked as dirty.
PR Close#44886
This new feature allows negative indices to wrap around from the back, just like ES2021 `Array.at`. In particular, the following methods accept negative indices, and behave like corresponding Array methods:
* `FormArray.at(index)`: behaves the same as `Array.at(index)`
* `FormArray.insert(index, control)`: behaves the same as `Array.splice(index, 0, control)`
* `FormArray.setControl(index, control)`: behaves the same as `Array.splice(index, 1, control)`
* `FormArray.removeAt(index, control)`: behaves the same as `Array.splice(index, 1)`
Previous work in #44746 and #44631 (by @amitbeck).
Issue #44642.
Co-authored-by: Amit Beckenstein <amitbeck@gmail.com>
PR Close#44848
This functionally dead code was originally introduced via pull request
were added to verify the fix, and the many comments on that issue after
it was closed indicate that it wasn't actually resolved.
In fact, setting `selectedIndex` does absolutely nothing here, since
the selected index is immediately overridden by setting the `value`
property. A working fix (with tests) for the IE/Safari bug is in pull
request #23784. Originally this dead code was removed as part of that PR,
but @AndrewKushnir recommended creating a separate PR for the cleanup.
PR Close#37614
Modified required validator and checkbox validator to inherit abstractValidator.
For every validato type different PR will be raised as discussed in #42378.
Closes#42267
PR Close#44162
This implementation change was originally proposed as part of Typed Forms, and will have major consequences for that project as described in the design doc. Submitting it separately will greatly simplify the risk of landing Typed Forms. This change should have no visible impact on normal users of FormControl.
See the Typed Forms design doc here: https://docs.google.com/document/d/1cWuBE-oo5WLtwkLFxbNTiaVQGNk8ipgbekZcKBeyxxo.
PR Close#44316
Modified email validator to inherit abstractValidator.
For every validato type different PR will be raised as discussed in #42378.
Closes#42267
PR Close#44545
This commit performs some refactoring of the AbstractControl-based classes to employ shared `RuntimeError` class and also updates the code to avoid duplication and improve minification.
PR Close#44398
This commit refactors the code of the base validators class to make it compatible with the property renaming optimization. Currently the code makes an assumption that the field with a specified name (defined as a string) can be found on an object, but with property renaming optimization this is not correct.
PR Close#44500
I previously strengthened some weak types in #44370. One of these fixes exposed an incorrect call into `_reduceChildren` from `_reduceValue`. This was caught in google3 by a caller who was extending `FormGroup` and overriding these methods.
Special thanks to Bart G for catching this issue and suggesting a fix.
PR Close#44483
Allow a FormControl to be reset to its initial value. Provide this feature via a new option in a FormControlOptions interface, based on AbstractControlOptions.
Also, expose the default value as part of the public API. This is part of a feature that has been requested elsewhere (e.g. in #19747).
This was originally proposed as part of typed forms. As discussed in the GDE session (and after with akushnir/alxhub), it is likely better to just reuse the initial value rather than accepting an additional default.
It is desirable to land this separately in order to reduce the scope of the typed forms PR, and make it a types-only change.
Pertains to issue #13721.
PR Close#44434
It is desirable to land this separately to reduce the scope of the Typed Forms PR, by focusing it only on the new type parameters (rather than incidental strictness fixes).
PR Close#44370
This reverts commit cdf50ff931.
Reverting as this needs a little more work on the documentation side, plus
the `export declare interface` syntax in `model.ts` might have unintended
side effects in g3.
This implementation change was originally proposed as part of Typed Forms, and will have major consequences for that project as described in the design doc. Submitting it separately will greatly simplify the risk of landing Typed Forms. This change should have no visible impact on normal users of FormControl.
See the Typed Forms design doc here: https://docs.google.com/document/d/1cWuBE-oo5WLtwkLFxbNTiaVQGNk8ipgbekZcKBeyxxo.
PR Close#44316
This commit updates the code of the `SelectMultipleControlValueAccessor` to:
- improve typings to make them more precise
- updates the note that refers to IE, but we still can not remove the branch since it's needed for Universal (that uses Domino)
PR Close#44261
Data members in AbstractControl should be eagerly
initialized to address issue/24571. This eliminates the need to
constantly check for truthiness and makes code much more readable.
More PRs to follow to address issue/24571.
PR Close#44292
This commit makes the `FormControlStatus` symbol available as a public API. The symbol itself
was intended to become a part of the public API, but due to the missing re-export, the symbol
remains private.
Fixes#44176.
PR Close#44183
This commit updates the code of the min/max and minlength/maxlength validator directives to inherit `ngOnChanges` hooks from the base class (the `AbstractValidatorDirective` one), rather than implementing the hooks on the child classes. This was needed to avoid issues with hooks inheritance in ViewEngine, but since it's deprecated, the code can be cleaned up.
PR Close#43945
Modified minlength and maxlength validator to inherit abstractValidator
For every validator type different PR will be raised as discussed in #42378.
Closes#42267
PR Close#43998
Modified minlength and maxlength validator to inherit abstractValidator
For every validator type different PR will be raised as discussed in #42378.
Closes#42267
PR Close#43835
This commit updates the logic of the `min` and `max` validators to allow
disabling them dynamically in case `null` is provided as a value. For example: `<input
type="number" [min]="minValue">`, when `minValue` might be set to `null` in a
component class. This should allow `min` and `max` validators to be used for dynamic forms.
Note: similar support was added to the `minLength` and `maxLength`
validators earlier (see #42565).
PR Close#42978
Currently the error message functions are defined as static methods on a class which means that as soon as one of them is used somewhere, all of them have to be retained. This isn't a problem at the moment, because all of them are behind `ngDevMode` checks, but it's error prone and it's easy to fix.
These changes move them out into functions so that they can be imported individually. It also has the advantage of allowing Webpack to minify the function names.
PR Close#43223
Specifically: narrow the type used for form statuses from string to a union of possible statuses. Change the API methods from any to use the new type.
This is a breaking change. However, as discussed in the PR, breakage seems minimal, and google3 has been prepped to land this.
Background: we uncovered these any typings in the course of design work for typed forms. They could be fixed in a non-breaking manner by piggybacking them on top of the new typed forms generics, but it would be much cleaner to fix them separately if possible.
BREAKING CHANGE:
A new type called `FormControlStatus` has been introduced, which is a union of all possible status strings for form controls. `AbstractControl.status` has been narrowed from `string` to `FormControlStatus`, and `statusChanges` has been narrowed from `Observable<any>` to `Observable<FormControlStatus>`. Most applications should consume the new types seamlessly. Any breakage caused by this change is likely due to one of the following two problems: (1) the app is comparing `AbstractControl.status` against a string which is not a valid status; or, (2) the app is using `statusChanges` events as if they were something other than strings.
PR Close#42952
Several new functionalities are possible with this change: the most requested is that callers can now check whether a control has a required validator. Other uses include incrementally changing the validators set without doing an expensive operation to reset all validators.
Closes#13461.
PR Close#42838
If the validator is bound to be `null` then no validation occurs and
attribute is not added to DOM.
For every validator type different PR will be raised as discussed in
https://github.com/angular/angular/pull/42378.
Closes#42267.
PR Close#42565
In combination with the TS `noImplicitOverride` compatibility changes,
we also want to follow the best-practice of adding `override` to
members which are implemented as part of abstract classes. This
commit fixes all instances which will be flagged as part of the
custom `no-implicit-override-abstract` TSLint rule.
PR Close#42512
When a FormControl, FormArray, or FormGroup is first constructed, if an async validator is attached, the `statusChanges` observable should receive a message when the validator complete (i.e. pending -> valid/invalid). If the validator was provided as part of the constructor options, it was not fired at construction time, which is fixed in this PR.
Fixes#35309.
PR Close#42553
As previously discussed in pull/31070 and issues/30486, this would be useful because it is often desirable to apply styles to fields that are both `ng-invalid` and `ng-pristine` after the first attempt at form submission, but Angular does not provide any simple way to do this (although evidently Angularjs did). This will now be possible with a descendant selector such as `.ng-submitted .ng-invalid`.
In this implementation, the directive that sets control status classes on forms and formGroups has its set of statuses widened to include `ng-submitted`. Then, in the event that `is('submitted')` is invoked, the `submitted` property of the control container is returned iff it exists. This is preferred over checking whether the container is a `Form` or `FormGroup` directly to avoid reflecting on those classes.
Closes#30486.
PR Close#42132.
This reverts commit 00b1444d12, undoing the rollback of this change.
PR Close#42132
For quite a while it is an unspoken convention to add a trailing
new-line files within the Angular repository. This was never enforced
automatically, but has been frequently raised in pull requests through
manual review. This commit sets up a lint rule so that this is
"officially" enforced and doesn't require manual review.
PR Close#42478