Home > Software design >  How to data bind to a Form Group within a Form Array? Angular
How to data bind to a Form Group within a Form Array? Angular

Time:12-04

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

  1. Would suggest writing a function for generating FormGroup for the skill object (initSkillFormGroup method).

  2. Call the initSkillFormGroup method and add it to skillsArray.

addSkills() {
  this.skillsArray.push(this.initSkillFormGroup());
}

initSkillFormGroup() {
  return new FormGroup({
    first_skill: new FormControl('', Validators.required),
    second_skill: new FormControl('', Validators.required),
  });
}
  1. (Optional) Writing the initSkillFormGroup method to avoid redundant declaring the FormGroup for skill object. Well, when you build the root form, you can initialize the skills 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>

Demo @ StackBlitz

  • Related