6

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);
}
4
  • Scrap my previous answer. The problem is most likely that you are not passing an array to setValue.
    – Tom
    Commented Jul 8, 2017 at 15:14
  • Should not to pass the index, to the specific array form? I am tryng this but this is not working setValue(index) { this.fData.setValue(['Name']); } The error says that must supply a value for fom control with name 'name'
    – LLaza
    Commented Jul 8, 2017 at 15:33
  • Try this: this.fData[index].controls['name'].setValue(['name'])
    – Tom
    Commented Jul 8, 2017 at 15:54
  • not working: Cannot read property 'controls' of undefined
    – LLaza
    Commented Jul 8, 2017 at 16:08

3 Answers 3

34

For arrays, you need to use setControl. Something like this:

    this.productForm = this.fb.group({
        productName: ['', [Validators.required,
                           Validators.minLength(3),
                           Validators.maxLength(50)]],
        productCode: ['', Validators.required],
        starRating: ['', NumberValidators.range(1, 5)],
        tags: this.fb.array([]),
        description: ''
    });

    ...

    // Update the data on the form
    this.productForm.patchValue({
        productName: this.product.productName,
        productCode: this.product.productCode,
        starRating: this.product.starRating,
        description: this.product.description
    });
    this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
11
  • 4
    I must have missed that in your pluralsight course ;-)
    – Tom
    Commented Jul 8, 2017 at 16:16
  • 1
    Found it: app.pluralsight.com/…
    – Tom
    Commented Jul 8, 2017 at 16:24
  • 2
    The "Angular: Reactive Forms" course? Hope it was helpful!
    – DeborahK
    Commented Jul 8, 2017 at 16:25
  • 1
    LOL! Wish we could add emojis to comments!
    – DeborahK
    Commented Jul 8, 2017 at 16:26
  • 1
    Thank you so much!!!! I was using control.push() but control.setControl() was exactly what I needed!!
    – Tyron
    Commented Aug 31, 2019 at 6:23
8

Here is what I have done to set value manually in formArray's specific form control and worked for me. I have formArray named as bundleDetails.

this.formBuilderObj['bundleDetails'] = 
this.formBuilder.array([this.createBundleItem()]);
   
createBundleItem(): FormGroup {
    return this.formBuilder.group({
        bsku: ['', Validators.required],
        bqty: ['', Validators.required],
        bprice: ['', Validators.required]
    });
}

Method to set bsku control's value (where index is [formGroupName]="i" passed from an HTML file).

setSku(sku: string, index: number) {
   const faControl = 
   (<FormArray>this.pmForm.controls['bundleDetails']).at(index);
   faControl['controls'].bsku.setValue(sku);
}
0
0

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.