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. 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' Commented Jul 8, 2017 at 15:33
  • Try this: this.fData[index].controls['name'].setValue(['name']) Commented Jul 8, 2017 at 15:54
  • not working: Cannot read property 'controls' of undefined 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 || []));
Sign up to request clarification or add additional context in comments.

11 Comments

I must have missed that in your pluralsight course ;-)
The "Angular: Reactive Forms" course? Hope it was helpful!
LOL! Wish we could add emojis to comments!
Thank you so much!!!! I was using control.push() but control.setControl() was exactly what I needed!!
|
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);
}

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.