I am trying to make an Angular Forms app that allows the user to input some information. The user will be required to fill basic information and add two sets of skills to the form at a time and add these are stored in array..
HTML:
<div >
<form (ngSubmit)="submit()" [formGroup]="myForm">
<h1>User Registration</h1>
<div >
<label for="firstname"></label>`
<input type="text" name="firstname" formControlName="name" />
<input type="text" name="firstname" formControlName="email" />
<div formArrayName="skills">
<ng-container *ngFor="let skill of skillsArray.controls; index as i">
<div formGroupName="skills">
<input
type="text"
name="firstname"
placeholder="my skill"
formControlName="name"
formControlName="first_skill"
/>
<input
type="text"
name="firstname"
placeholder="my skill"
formControlName="name"
formControlName="second_skill"
/>
</div>
<button (click)="addSkills()">Add Skills</button>
</ng-container>
</div>
<button type="submit">Submit</button>
</div>
<br />
<div >
{{ myForm.value | json }}
<br />
{{ myForm.valid | json }}
</div>
</form>
</div>
TS:
export class FormCompComponent implements OnInit {
myForm!: FormGroup;
constructor (private fb : FormBuilder) {
}
ngOnInit(): void {
this.myForm = new FormGroup({
name: new FormControl('', Validators.required),
email: new FormControl('', Validators.required),
skills: new FormArray([
new FormGroup({
first_skill: new FormControl('', Validators.required),
second_skill: new FormControl('', Validators.required),
})
]),
});
}
addSkills() {
this.skillsArray.push(new FormControl('', Validators.required));
}
get skillsArray() {
return this.myForm.get('skills') as FormArray;
}
submit() {
console.log(this.myForm.value);
}
}
From an interface perspective, everything is okay, I am able to add items to the array successfully but I am struggling to bind my input to my typescript objects
These are my results when inputting:
{ "name": "test", "email": "test", "skills": [ { "first_skill": "", "second_skill": "" }, "" ] }
How do i penetrate the nested objects from my HTML?
I am currently looping over the array and then attempting to access formGroupName.
My inputs register as blank. why is this?
Thanks,
CodePudding user response:
Issue 1: Incorrectly add FormGroup
into FormArray
From here:
addSkills() {
this.skillsArray.push(new FormControl('', Validators.required));
}
You are adding FormControl
into skills
FormArray
, it supposes to be adding the FormGroup
instead.
Solution for Issue 1
Would suggest writing a function for generating
FormGroup
for theskill
object (initSkillFormGroup
method).Call the
initSkillFormGroup
method and add it toskillsArray
.
addSkills() {
this.skillsArray.push(this.initSkillFormGroup());
}
initSkillFormGroup() {
return new FormGroup({
first_skill: new FormControl('', Validators.required),
second_skill: new FormControl('', Validators.required),
});
}
- (Optional) Writing the
initSkillFormGroup
method to avoid redundant declaring theFormGroup
forskill
object. Well, when you build the root form, you can initialize theskills
FormArray
by calling the mentioned function.
this.myForm = new FormGroup({
...,
skills: new FormArray([this.initSkillFormGroup()]),
});
Issue 2: Incorrectly generate each skill
FormGroup
in skills
FormArray
Solution for Issue 2
Pass the i
to [formGroupName]
attribute.
<ng-container *ngFor="let skill of skillsArray.controls; index as i">
<div [formGroupName]="i">
...
</div>
</ng-container>