I'm building a CRUD app using Angular 6.
My forms are used for adding and updating items. When the user updates an item, the form is pre-populated from the server. When the server updates the form it triggers the validation.
How can I update the form values without triggering the validation?
Here is the relevant code:
ngOnInit(){
this.form = this.fb.group({
name: ['', [Validators.required], MyAsyncValidator],
comments: [''],
});
this.http.get('/api')
.subscribe((data: any) => {
this.form.setValue({ name: data.name, comments: data.comments });
});
//How to populate form without triggering validation
}
The template:
<form [formGroup]="form">
<div class="form-group row">
<label class="col-sm-2 col-form-label">Name</label>
<div class="col-sm-10">
<input formControlName="name"
class="form-control"
[ngClass]="{'is-invalid': isInvalid(form.controls.name)}"
type="text">
<small *ngIf="form.get('name').status=='PENDING'" class="form-text text-muted">
<i class="fa fa-spinner fa-spin"></i> Checking Name...
</small>
<small class="invalid-feedback">
<div *ngIf="form.controls['name'].hasError('required')">Name Required</div>
<div *ngIf="form.controls['name'].hasError('exists')">Name Exists</div>
</small>
</div>
</div>
I think this is either a bug in angular or some weird behaviors implemented in the code. I had the same issue and debugged through the source code only to find this:
setValue will call to updateValueAndValidity(): https://github.com/angular/angular/blob/39c8baea318e740111b1c748718c3203a61b4cdf/packages/forms/src/model.ts#L941
and in updateValueAndValidity(), it calls asyncValidatior: https://github.com/angular/angular/blob/39c8baea318e740111b1c748718c3203a61b4cdf/packages/forms/src/model.ts#L554
My impression is that when setting emitEvent: false
, no validation should be triggered, however, this is not the case. What is even weirder is the fact that no matter if you set updateOn
to change
or blur
the asyncValidator will be triggered on setValue.
I have no option but to remove asyncValidator before every setValue call and add it back afterwards.
Just faced same problem.
Calling control.markAsTouched()
before calling control.setValue(value)
worked for my case.
Does this mean validation fails only when the control is touched? hm...
I'm using Angular 7 btw
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With