Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: Update FormControl validator after valueChanges

Is there a way to update the Validtors of a FormControl Object? I have FormGroup where one Input is a select field, when the value of the select field changes I want the other FormControl in my FormGroup to change the validator.

Here is my subscribeToFormChanges() method from my FormGroup component:

private appIdRegexes = {
    ios: /^[a-zA-Z][a-zA-Z0-9]*(\.[a-zA-Z0-9\-]+){2,}$/,
    android: /^([a-zA-Z])[a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9\-]*){2,}$/,
    any: /^any$/
  };

private subscribeToFormChanges(): void {
    const myFormValueChanges$ = this.appsForm.valueChanges;
    myFormValueChanges$.subscribe(x => {
      const platform = this.appsForm.controls['platform'].value;
      const appId = this.appsForm.controls['appId'].value;

      if (this.appIdRegexes[platform]) {
        this.appsForm.controls['appId'] = new FormControl(appId, Validators.pattern(this.appIdRegexes[platform].source));
      }
    });
  }

And here's the html template:

<div class="row" [formGroup]="appsForm">
  <div class="form-group col-xs-6">
    <label>Platform</label>

    <select id="licensePlatform" class="form-control"
            formControlName="platform">
      <option *ngFor="let platform of licensePlatforms" [value]="platform">
        {{platform}}
      </option>
    </select>

    <small [hidden]="appsForm.controls.platform.valid">
      Platform is required
    </small>
  </div>

  <div class="form-goup col-xs-6">
    <label>App ID</label>
    <input type="text" class="form-control" formControlName="appId">
    <small [hidden]="appsForm.controls.appId.valid">
      Please use the right ID format
    </small>
  </div>
</div>

When I'm implementing the subscribeToFormChanges() method like shown here, appsForm.controls.appId.value doesn't update anymore when writing into the input field. Initially the value is updating.

like image 884
Markus Török Avatar asked Oct 06 '16 13:10

Markus Török


2 Answers

I solved the issue by listening to valueChanges on my platform select field and then I use the setValidators() method on the appId input field. This article was quite helpful.

Here's my solution:

 private subscribePlatformChanges() {
    const platformCtrl = this.appsForm.controls['platform'];
    const changes$ = platformCtrl.valueChanges;

    changes$.subscribe(platform => {
      this.appsForm.controls['appId'].setValidators([Validators.pattern(this.appIdRegexes[platform].source),
                                                    Validators.required]);
      this.appsForm.controls['appId'].updateValueAndValidity();
    });
  }
like image 188
Markus Török Avatar answered Oct 17 '22 11:10

Markus Török


To recheck the controls within a FormGroup, you can do something with the updateValueAndValidity of the FormControl.

If this.appsForm is indeed a FormGroup:

this.appsForm.controls.forEach(control => control.updateValueAndValidity());
like image 5
Poul Kruijt Avatar answered Oct 17 '22 11:10

Poul Kruijt