Search code examples
angularangular-validationangular-formbuilder

How to get Angular 8 to validate my form fields after I dynamically inject input values after the page has loaded?


Angular's form validator doesn't seem to check if an input item is valid after I dynamically set an inputs value by clicking a button.

On my form, I have a button which when clicked calls an API and uses the returned data to populate some fields. However the method I am using doen't envoke angulars validation checker. This might be because the user doesn't actually ever click into the form field and manually set the data... Thus, the validator never gets envoked. If the user does type some data into the field, the form gets validated fine.

What is the best way I can overcome this error? Am I taking the wrong approach to set these values? I want the form to be validated, but the user shouldn't necessarially have to click into and type the fields value.

I have created a stripped down version of my form on StackBlitz. View it Here

And below is the same code:

app.component.html:

<form [formGroup]="generalFormGroup">
  <button type="button" (click)="populateData()">Populate default data</button>
  <input type="text" placeholder="Title" formControlName="inputTitle" [value]="itemTitle" (input)="itemTitle = $event.target.value">
  <button type="button" (click)="onSubmit()" [disabled]="generalFormGroup.invalid">Save</button>
</form>

app.component.ts:

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {

  generalFormGroup: FormGroup;
  itemTitle = '';

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.initForm();
  }

  initForm() {
    this.itemTitle = '';
    this.generalFormGroup = this.formBuilder.group({
      inputTitle: [this.itemTitle, Validators.required]
    });
  }

  populateData() {
    this.itemTitle = 'Some title here';
  }

  onSubmit() {
    if (this.generalFormGroup.valid) { console.log('the form is valid'); }
    else { console.log('the form is invalid'); }
  }
}

Solution

  • When using reactive form in angular you should update the value in model instead of updating value in template. In your example you are using value attribute to update the value, It will not update formControl instance in ts file. Remove value attribute from template. Use form control setValue or patchValue to set the value dynamically.

    component.html

    <form [formGroup]="generalFormGroup">
      <button type="button" (click)="populateData()">Populate default data</button>
      <input type="text" placeholder="Title" formControlName="inputTitle">
      <button type="button" (click)="onSubmit()" [disabled]="generalFormGroup.invalid">Save</button>
    </form>
    

    component.ts

     populateData() {
        this.generalFormGroup.get('inputTitle').setValue('some title here');
      }
    

    Example