5

I am wondering if there is any method to set value and update validity of a control of a form. Given the following:

this.updateForm = this._formBuilder.group({
    user: ['',Validators.required]     
});

I have some directive which has on change trigger, that triggers the following:

changeUserSelection(value){
    this.updateForm.controls['user'].value = value // doesnt trigger validation?
}

And I am wondering how I can set the value, and trigger validation of this field. Doing this my way, doesnt trigger validation.

Thanks

uksz
  • 18,239
  • 30
  • 94
  • 161

5 Answers5

9

Update to Angular2 final

As per angular2's final release updateValue has been changed to setValue so the new syntax should be like this

changeUserSelection(value){
  this.updateForm.controls['user'].setValue(value);
}
Community
  • 1
  • 1
Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215
  • The `updateValueAndValidatity` need to be called to trigger the validator functions. – Yuanfei Zhu Dec 05 '16 at 10:35
  • 7
    Also notice that `setValue` won't update the pristine status of the control. `markAsDirty` need to be called explicitly. – Yuanfei Zhu Dec 05 '16 at 10:36
  • yeah exactly @YuanfeiZhu – Pardeep Jain Dec 05 '16 at 11:12
  • 2
    Sometimes `markAsTouched()` is what's needed. With Angular material and the default ErrorMatcher - a control won't show its error message until it is 'touched'. It doesn't need to actually be 'dirty'. – Simon_Weaver Jul 13 '20 at 19:41
  • @Simon_Weaver seems you are right, if you wish to edit my answer, i would be more than happy to approve, please go ahed. – Pardeep Jain Jul 14 '20 at 04:56
  • @PardeepJain thanks for the reply. It seems for my situation I needed both `markAsTouched()` and `updateValueAndValidity`. There can be a lot of subtleties so maybe best to leave the answer as it is and hope people read and consider the comments. It's a whole project to consider all the possibilities - plus things like Angular Material adds extra complexity with ErrorStateMatcher (see https://stackoverflow.com/a/54050451/16940). – Simon_Weaver Jul 14 '20 at 05:29
  • `dirty` means the value has changed, whereas `touched` just means it had focus. To be honest for most cases it probably wouldn't have an impact unless you had some very special needs. – Simon_Weaver Jul 14 '20 at 05:31
7

For me setValue, patchValue did not do the job by themselves. What I did to trigger the validation is the following:

form.controls[field].setValue(value);
form.controls[field].markAsTouched();
form.controls[field].markAsDirty();
form.controls[field].updateValueAndValidity();

That way my validation messages were triggered correctly. I tried without updateValueAndValidity but it did not work.

Vallerious
  • 570
  • 6
  • 13
4

You should use the updateValue method instead:

changeUserSelection(value){
  this.updateForm.controls['user'].updateValue(value);
}
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • In which verison of angular was this introduced? – uksz Mar 31 '16 at 13:35
  • For some reason my TS doesnt see this, and I get an error: Property 'updateValue' does not exist on type 'AbstractControl'. – uksz Mar 31 '16 at 13:37
  • 1
    Yes because the method is located into the `Control` class not in the `AbstractControl` one. `Control` extends `AbstractControl`. See https://github.com/angular/angular/blob/master/modules/angular2/src/common/forms/model.ts#L294 – Thierry Templier Mar 31 '16 at 13:38
  • wait. but when I build a form using formBuilder, it returns AbstractControls...right? – uksz Mar 31 '16 at 13:41
  • Yes but you try to set the value on an input control within the form. In this case, it's a Control, i.e. `this.updateForm.controls['user']`. – Thierry Templier Mar 31 '16 at 13:43
  • Thats weird. We can see that export declare class ControlGroup extends AbstractControl { controls: { [key: string]: AbstractControl; }; . Hence, it is an abstractControl. – uksz Mar 31 '16 at 13:43
  • Yes because you can create sub group and in this case, it's a control group not a control. See this question: http://stackoverflow.com/questions/35413693/cross-field-validation-in-angular2/35414956#35414956. But for a control that corresponds to an input, it's a control. – Thierry Templier Mar 31 '16 at 13:47
4

You could also try patchValue

this.updateForm.patchValue({ user: value });
Mackelito
  • 4,213
  • 5
  • 39
  • 78
0

You can try this.form.updateValueAndValidity(); to update value and validation for multiple controls.