Search code examples
javascripthtmlangulartypescriptangular-forms

Looping through form array inside form group angular


I get list of data from server and i want to show them inside a list of spans as below:

enter image description here

Each row correspond to one item of list and note that I create this list with *ngFor as below:

this.myForm = this.fb.group({
            person: this.fb.array([
                this.fb.group({
                    name: [''],
                    address: ['']
                })
            ])
        })
<form [formGroup]="myForm">
      <div formArrayName="person" *ngFor="let person of serverData; let personIndex = index">
          <div [formGroupName]="personIndex">
              <input formControlName="name"/>
              <input formControlName="address"/>
          </div>
      </div>
</form>

After running this code the browser gives me this:

Error:

No value accessor for form control with path: 'person -> 0 -> name'

But I know that I should use myForm.controls.person.controls instead of serverData in for loop, but I want to have both list and controls together.

Should I use two for loops that one of them iterates over server data and the other one iterates over form controls or I should use another way?


Solution

  • You must push all objects from serverData to your formarray, so that the array lengths are the same as the serverData array. Your template stays as it currently is, but in component, map the values from serverData and push the objects with the properties you want to the formarray:

    constructor(private fb: FormBuilder) {}
    
    ngOnInit() {
      this.myForm = this.fb.group({
        persons: this.fb.array([])
      });
      this.data();
    }
    
    get person() {
      return this.myForm.get("persons") as FormArray;
    }
    
    private data() {
      this.serverData = [
        {
          name: "1",
          desc: "one"
        },
        {
          name: "2",
          desc: "two"
        },
        {
          name: "3",
          desc: "three"
        }
      ];
    
      this.serverData.map(d =>
        this.person.push(this.fb.group({ name: d.name, address: d.desc }))
      );
    }
    

    DEMO: STACKBLITZ