Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 6: don't trigger validators setValue

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>

like image 294
Thibs Avatar asked Jun 25 '18 13:06

Thibs


2 Answers

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.

like image 173
zokland Avatar answered Nov 11 '22 13:11

zokland


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

like image 38
Ryan Teh Avatar answered Nov 11 '22 13:11

Ryan Teh