Kamran Taghaddos
Kamran Taghaddos

Reputation: 594

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?

Upvotes: 2

Views: 8166

Answers (2)

AVJT82
AVJT82

Reputation: 73357

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

Upvotes: 1

Eliseo
Eliseo

Reputation: 57929

NOTE: I like the loop is n the div of fromGroupName

<form [formGroup]="myForm">
      <div formArrayName="person"> >
          <div *ngFor="let person of serverData; let personIndex = index"
               [formGroupName]="personIndex">
              <span formControlName="name">{{person.name}}</span>
              <span formControlName="address">{{person.address}}</span>
          </div>
      </div>
</form>

If you iterate over myForm.controls.person.controls, always formGroupName has value, if you has an array and declare BEFORE create the form, At very first state of the application, the FormArray is not created

Upvotes: 1

Related Questions