Skip to content

setValidators() does not mark form ng-invalid properly. #19622

@kbpontius

Description

@kbpontius

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

The validation state for a form is only evaluated when first created. If setValidators() is called after all "lifecycle" events have been called (e.g. ngOnInit()), the form doesn't update its validation state properly. As a side note, calling reset() on the FormGroup after using setValidators() will correctly reevaluate the validators and set the appropriate fields to ng-invalid. This seems like a possible workaround for the time being.

Detailed Example:

  1. Form controls are initially set up in constructor with validators.
  2. One of the controls is not required when the form is initially created.
  3. After the component has stabilized, after all life-cycle events have been called, a method is called (perhaps by clicking a button) which calls setValidators() on the FormControl that wasn't previously required and sets a new required validator on that control.

Observe the DOM at this point. If the form has not been clicked on or modified in any way, that control that was updated with the new required validator fails to have the class ng-invalid. If it was the only control on the form, or all others pass validation by default, the form would be marked ng-valid.

It's worth noting that if the newly "required" field is modified, the validators then run and work correctly thereafter.

Also worth nothing: In a scenario where there are two FormControls, where Control B is required, but Control A is not. If setValidators() is called on Control A to add the required validator, without subsequently touching or filling in Control A, then B is filled in to satisfy its required state, the form is marked as valid, incorrectly.

Expected behavior

When setValidators() is called, the form should reevaluate all fields with the new validation, as if the validation had been configured with the new validators when the FormGroup was initialized.

Minimal reproduction of the problem with instructions

This Plunker functions correctly, but I couldn't get Angular Material to work.

http://plnkr.co/edit/5SGJAADfQZRxqFGrSyYL

What is the motivation / use case for changing the behavior?

It seems reasonable to expect the form to update its validation state when setValidators() is called. Any new validators should be immediately evaluated when set. For example, if a field that wasn't previously required is not required, the form's validation state should update as such when setValidators() is called.

Environment


Angular version: 4.2.5 (verified the problem is occurring on 4.4.4 as well)

Browser:
- [X] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 6.9.3
- Platform: Mac

Others:
No other relevant notes.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions