Saturday 2 February 2019

Angular populate formarray

Angular populate formarray


We want to populate the skills FormArray, with the existing skills an employee has. 

For example, consider the following data of an existing employee. 

{
  "id"2,
  "fullName""John",
  "contactPreference""phone",
  "email""john@email.com",
  "phone""3242138971",
  "skills": [
    {
      "skillName""Angular",
      "experienceInYears"2,
      "proficiency""beginner"
    },
    {
      "skillName""HTML",
      "experienceInYears"2,
      "proficiency""intermediate"
    },
    {
      "skillName""LINQ",
      "experienceInYears"3,
      "proficiency""advanced"
    }
  ]
}

When we load this data on a form to edit this employee details, we want to populate skills FormArray as shown below. 

angular populate formarray 

To achieve this modify editEmployee() method in create-employee.component.ts as shown below. 

Notice we are using setControl() method to replace the skills FormArray with the FormArray that setExistingSkills() method returns. 

editEmployee(employee: IEmployee) {
  this.employeeForm.patchValue({
    fullName: employee.fullName,
    contactPreference: employee.contactPreference,
    emailGroup: {
      email: employee.email,
      confirmEmail: employee.email
    },
    phone: employee.phone
  });

  this.employeeForm.setControl('skills'this.setExistingSkills(employee.skills));
}

setExistingSkills() method 
  • loops through each skill object of an employee
  • Creates a FormGroup with 3 form controls (skillName, experienceInYears, proficiency)
  • Pushes the FormGroup into the FormArray
  • Finally, this FormArray with the existing skills of the employee is returned
setExistingSkills(skillSets: ISkill[]): FormArray {
  const formArray = new FormArray([]);
  skillSets.forEach(s => {
    formArray.push(this.fb.group({
      skillName: s.skillName,
      experienceInYears: s.experienceInYears,
      proficiency: s.proficiency
    }));
  });

  return formArray;
}

Important - Programmatically changing a formarray in angular does not change dirty state : At this point, if you remove one of the skill groups from the FormArray by clicking the "Delete Skill" button, notice the dirty and touched state of the form is still false 

This is because, the state properties like dirtytouched etc are designed to indicate whether a user has interacted with the form. 

By default, programmatic change to value of a form control will not flip the value of these properties. However, in some cases you may need to mark form controls, form groups and form arrays as touched, dirty etc. In such cases you can explicitly do so by calling markAsDirty() and markAsTouched() methods.

In our case, when a SKILL form group is removed from the FormArray we want to mark the formArray as touched and dirty. To achieve this, we are using markAsDirty() and markAsTouched() methods. 

removeSkillButtonClick(skillGroupIndex: number): void {
  const skillsFormArray = <FormArray>this.employeeForm.get('skills');
  skillsFormArray.removeAt(skillGroupIndex);
  skillsFormArray.markAsDirty();
  skillsFormArray.markAsTouched();
}

No comments:

Post a Comment