Home > Mobile >  Angular formArray inside formArray
Angular formArray inside formArray

Time:02-21

I am doing inline editing in my project, i am trying to patchvalue data from server, i have formarray inside the formArray for my accountNumbers array, but when i try to change value of inputs it gives error: Error: Cannot find control with path: 'type -> options -> 0 -> accountNumbers -> accountNumber' what am i doing wrong? here is my stackblitz

.ts

    this.editCompanies = this._formBuilder.group({
      type: this._formBuilder.group({
        options: this._formBuilder.array([]),
      }),
    });

    const control = <FormArray>this.editCompanies.get('type.options');
    this.items.forEach((x) => {
      control.push(
        this.patchValues(x.name, x.identificationCode, x.accountNumbers)
      );
      console.log(control);
    });
  }

  patchValues(name, identificationCode, accountNumbers) {
    return this._formBuilder.group({
      name: [name],
      identificationCode: [identificationCode],
      accountNumbers: new FormArray([this.initOptions()]),
    });
  }

  initOptions() {
    return new FormGroup({
      accountNumber: new FormControl(''),
    });
  }

.html

  <div >
    <span formArrayName="accountNumbers">
        <span  [ngClass]="{'my_class': hidemeSub[index] === true}"
        [hidden]="hidemeSub[index]"> {{item.accountNumbers}}</span>
        <input type="text"  formControlName="accountNumber" [hidden]="!hidemeSub[index]">
    </span>
  </div>

CodePudding user response:

If you look at the path, you can see that your missing the index of the elemento of the second FormArray.

type -> options -> 0 -> accountNumbers -> [missing_index] -> accountNumber

Similar as you are assigning the first FormArray index using:

<div  formArrayName="options"
    *ngFor="let item of items; let index = index;">
    <ng-container [formGroupName]="index">

You need also to loop through the second array items and assign this second index using the proper ControlName directive. Since its also an array of FormGroup, you could do something like this:

<ng-container 
  *ngFor="let accountNumber of item.accountNumbers; let accIndex = index" 
  [formGroupName]="accIndex"
>
  <input type="text"  formControlName="accountNumber" [hidden]="!hidemeSub[index]">
</ng-container>

EDIT

You also need to properly initialize the FormGroup for the account numbers, creating one group per account:

patchValues(name, identificationCode, accountNumbers) {
  return this._formBuilder.group({
    ...
    accountNumbers: new FormArray(
      accountNumbers.map((account) => this.createAccountControl(account))
    ),
  });
}


//I renamed the method initOptions to better reflect the purpose
createAccountControl(initialValue: string = '') {
  return new FormGroup({
    accountNumber: new FormControl(initialValue),
  });
}

Cheers

  • Related