Sasi Kumar
Sasi Kumar

Reputation: 31

@for not able to iterate formarray in angular 19

I create one formgroup like this

getUserInfoForm(data?: UserInfo) {

return this.formBuilder.group({

name: [data?.name ? data.name : null, [Validators.required]],

age: [data?.age ? data.age : null, [Validators.required, Validators.min(18),Validators.max(99)]],

gender: [data?.gender ? data.gender : null, [Validators.required]],

hobbies: this.formBuilder.array([]),

})

}

This is my ts:

ngOnInit() {

this.userInfo = this.formsService.getUserInfoForm();

this.addHobby();

}

getHobbies(): FormArray{

return this.userInfo.get('hobbies') as FormArray;

}

addHobby(data?: string) {

this.getHobbies().push(data ? new FormControl(data) : new FormControl(''))

}

removeHobby(index: number) {

this.getHobbies().removeAt(index);

}

Here I'm able to iterate hobbies list using *ngFor

<div class="col-12 d-flex justify-content-between" formArrayName="hobbies">
        <label>Hobbies</label>
        <div *ngFor="let hobby of getHobbies().controls; let i = index" class="d-flex gap-5 justify-content-start w-50">
          <input class="form-control w-50" type="text" [formControlName]="i">
          <button type="button" class="btn btn-primary" >Add</button>
          <button type="button" class="btn btn-secondary" >Remove</button>
        </div>
      </div>

but I'm unable to do this using @for()

 <div class="col-12 d-flex justify-content-between">
        <label>Hobbies</label>
        @for(hobby of getHobbies().controls; track $index) {
          <div class="d-flex gap-5 justify-content-start w-50">
            <input class="form-control w-50" type="text" name="hobby" formControlName="hobby">
            <button class="btn btn-primary">Add</button>
            <button class="btn btn-secondary">Remove</button>
          </div>
        }
      </div>

Facing below error:

Type Array<AbstractControl<any>> must have a [Symbol. iterator]() method that returns an iterator.

enter image description here

Upvotes: 3

Views: 147

Answers (2)

Jeevan
Jeevan

Reputation: 83

<form [formGroup]="form">
  <div formArrayName="hobbies">
    <label>Hobbies</label>

    @for(hobby of getHobbies().controls; track hobby; let i = $index) {
     <div>
       <input type="text" name="hobby" [formControlName]="i">
       <button (click)="addHobby()">Add</button>
       <button (click)="removeHobby(i)">Remove</button>
     </div>
    }
  </div>
</form>

You have missed to add formArrayName directive

Upvotes: 0

Andres2142
Andres2142

Reputation: 2897

The new Control Flow from Angular should work using @for. In the code you posted using the new @for, you are missing a formArrayName, additionally, the formControlName for each input field should have a unique name which would be the index, that's also missing in your code.

I am not sure if the HTML posted is exactly how you want to look but you should be able to make it work like this:

<form [formGroup]="form">
  <div formArrayName="hobbies">
    <label>Hobbies</label>

    @for(hobby of getHobbies().controls; track hobby; let i = $index) {
     <div>
       <input type="text" name="hobby" [formControlName]="i">
       <button (click)="addHobby()">Add</button>
       <button (click)="removeHobby(i)">Remove</button>
     </div>
    }
  </div>
</form>

Take a look a this demo

Upvotes: 1

Related Questions