Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force Angular 2 to re-check validator?

I have a simple login form written in Angular 2 reactive (data-driven) template. It's working perfectly but when I refresh the page and browser fills e-mail+password (autocomplete), my form's valid property seems false.

But when I press any key or click anywhere in my page while form is invalid, angular updates some states (I guess) and my form become valid.

How can I trigger that state? How can I say angular "Hey, check my form again."? I can't trigger my own validation script because some validation messages are alerts. If I do this, when user open this page, he/she will see these alerts.

I remember, I use trigger('input') trick to update ng-model.

like image 789
Sam Avatar asked Feb 10 '17 12:02

Sam


1 Answers

updateValueAndValidity() is what you are looking for. The document is here: AbstractControl. It can force recalculate the value and validation status of the control.

Here's a demo:

form.component.ts

export class FormComponent implements OnInit {
  myform: FormGroup;

  // explicit validation of each field
  emailValid: AbstractControl;
  passwordValid: AbstractControl;

  constructor(private fb: FormBuilder) {
    this.myform = fb.group({
      'email': ['', Validators.required],
      'password': ['', Validators.required],
    });

    this.emailValid = this.myform.controls['email'];
    this.passwordValid = this.myform.controls['password'];
  }

    ngOnInit() {
        this.myform.get('email').valueChanges.subscribe(()=>forceValidAgain());
        this.myform.get('password').valueChanges.subscribe(()=>forceValidAgain());
    }

  forceValidAgain(){
    this.emailValid.updateValueAndValidity();
    this.passwordValid.updateValueAndValidity();
  }
}

form.component.html

<form [formGroup]="myform" (ngSubmit)="onSubmit(myform.value)">
  <div class="form-group">
    <label for="email">Email</label>
    <input type="email"
           class="form-control"
           id="email"
           name="email"
           [formControl]="myform.controls['email']"
           [ngClass]="{'is-invalid': !emailValid.valid && emailValid.touched }">
    <div
      class="invalid-feedback"
      *ngIf="emailValid.hasError('required')">
      This field is required
    </div>
  </div>

  <div class="form-group">
    <label for="password">Password</label>
    <input type="password"
           class="form-control"
           id="password"
           name="password"
           [formControl]="myform.controls['password']"
           [ngClass]="{'is-invalid': !passwordValid.valid && passwordValid.touched}">
    <div
      class="invalid-feedback"
      *ngIf="passwordValid.hasError('required')">
      This field is required
    </div>
  </div>
</form>
like image 186
Mingzhen Zhuang Avatar answered Sep 19 '22 13:09

Mingzhen Zhuang