Reputation: 31
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.
Upvotes: 3
Views: 147
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
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