简体   繁体   中英

Reactive Form nested FormArray with dynamic Field

I will be getting list of items and their hobbylist from backend, User should able to edit/add.

let item of ['item1', 'item2', 'item3']

(ngSubmit) value;

I want to following output:

item1: {
hobbyList: Array[0]
name: null
}, 
item2: {
hobbyList: Array[0]
name: null
}, 
item3: {
hobbyList: Array[0]
name: null
}

I have tried doing this but getting below error

ERROR
Error: Cannot find control with name: 'item1.hobbyList'
Unable to display error. Open your browser's console to view.

Is there any other way to achieve this.

Link: What i have tried so far Stackblitz: https://stackblitz.com/edit/angular-qsq3yb?file=src%2Fapp%2Fapp.component.ts

if you want to create the following array:

item1: {
    hobbyList: Array[0]
    name: null
}, 
item2: {
    hobbyList: Array[0]
    name: null
}, 
item3: {
    hobbyList: Array[0]
    name: null
}

then you need just to use map function:

let fooArray = ['item1', 'item2', 'item3'];
let desiredArray = fooArray.map(a => {
    let obj = {};
    obj[a] = {
        hobbyList:[],
        name : ''
    };
    return obj;
});
console.log(desiredArray);

stackblitz

  public myForm: FormGroup;

  ngOnInit() {
    this.myForm = new FormGroup({});
    for(let item of ['item1', 'item2', 'item3']) {
      this.myForm.addControl(item,
        new FormGroup({
          name: new FormControl(),
          hobbyList: new FormArray([])
        })
      )
    } 
  } 

  onAddHobby(group:FormGroup) {
    (group.get('hobbyList') as FormArray).push(new FormControl())
  }

  hobbiesArray(group:FormGroup):FormArray
  {
    return group.get('hobbyList') as FormArray
  }

The.html

<form [formGroup]="myForm">
    <ng-container *ngFor="let group of myForm.controls |keyvalue">
        <div style="margin:20px;" [formGroup]="group.value">
            <label for="">{{group.key}}</label>
            <input type="text" formControlName="name">
            <button type="button" (click)="onAddHobby(group.value)">Add Hobbies</button>
            <div formArrayName="hobbyList">
                <div *ngFor="let item of hobbiesArray(group.value).controls; let i = index">
                    <label for="">Hobbies</label>
                    <input [formControlName]="i">
      </div>
                </div>
        </div>
    </ng-container>
</form>
<pre>
{{myForm?.value|json}}
</pre>

But let me explain a bit the code. You has a FormGroup with three FormGroup, each of them has a FormControl and a FormArray. I like iterate always over the form of over elements of the form, it's the reason to iterate over some "bizarro" like let group of myForm.controls |keyvalue under this div, group.value will be each FormGroup, and group.key will be the name of the propertie.

As is a FormGroup, we create a div with this [formGroup]

<div style="margin:20px;" [formGroup]="group.value">
 ...
</div>

Under this div, we ask about the formControl "name" using

<input type="text" formControlName="name">

And about the formArray like

<div formArrayName="hobbyList">

We has a function to get the formArray, hobbiesArray(group.value) that pass the FormGroup, identically in onAddHobby we pass the FormGrorup

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM