How to set value in array form with Angular

Viewed 32618

I want to set value in array like this:

this.form.controls[name].setValue('name')

but I am working with array forms, and this is not working, even if I pass an array index explicitly

for example, this is my form array and I want to do is to set value in a function

user: FormGroup;
users: FormGroup;

constructor(private fb: FormBuilder) {}
ngOnInit() {
  this.user = this.buildGroup();
  this.users = this.fb.group({
    data: this.fb.array([this.user])
  });
}
get fData() {
  return this.users.get('data') as FormArray;
}
buildGroup() {
  return this.fb.group({
    name: ['', [Validators.required, Validators.minLength(2)]],
    account: this.fb.group({
      email: ['', Validators.required],
      confirm: ['', Validators.required]
    })
  });
}
setValue(index) {
  // This doesn't work
  this.fData[index].controls[name].setValue('name')
}
onSubmit() {
  this.fData.push(this.buildGroup());
  const {valid, value} = this.fData;
  console.log(valid, value);
}
3 Answers

If you're getting the error "ERROR Error: Cannot find control with path: 'addresses -> 0 -> addressType'" or something similar, it's most likely cause you're passing the values in but your html template is expecting values along with a control name.

To resolve this, iterate over each item in your array, and create a new form group instance for each value - based on what your view is expecting - then push to a new array variable, which we then set in our form.

See code below:

var tagsArray = [];
this.product.tags.forEach(product => tagsArray.push(this.fb.group({tag: [product.tag, [Validators.required]]})));
this.productForm.setControl('tags', this.fb.array(tagsArray || []));

Referenced in view like so:

<div class="tag" *ngFor="let t of tags.controls; let i = index" [formGroupName]="i" class="mb-2">
      <input type="text" formControlName="tag" placeholder="Tag name" class="primary_input">
       <button mat-icon-button (click)="deleteTag(i)">
           <mat-icon>clear</mat-icon>
       </button>
 </div>

This lets you load previous results while enabling the ability to add more values and validate user input.

Hope this helps.

Related