Search code examples
angularforeachformarray

.forEach is not a function on fromArray angular


I am working on a requirement where I have to loop through 'formArray' controls defined in component.ts file to set the validations on form submit. I am getting an error like ".forEach is not a function" Mycode is below:

component.ts

ip_addresses_arr: any;

this.companyForm = this.fb.group({
   company_ip_addresses: this.fb.array([this.fb.group({
    id: 0,
    start_ip: new FormControl('', Validators.pattern("^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$")),
    end_ip: new FormControl('', Validators.pattern("^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$"))
  })]),
});

My forEachloop on formArray is:

saveCompanyInfo() {
  this.ip_addresses_arr = this.companyForm.get('company_ip_addresses');
  this.ip_addresses_arr.forEach(eachfield => {
    console.log("each field",this.ip_addresses_arr);
    if(eachfield.start_ip != "" && eachfield.end_ip == ""){
      console.log("coming inside end_ip is empty");
      eachfield.end_ip.setErrors({'incorrect': true});
      eachfield.end_ip.markAsTouched();
    }else if(eachfield.end_ip != "" && eachfield.start_ip == ""){
      console.log("coming inside start_ip is empty");
      eachfield.start_ip.setErrors({'incorrect': true});
      eachfield.start_ip.markAsTouched();
    }else{
      eachfield.start_ip.setErrors(null);
      eachfield.end_ip.setErrors(null);
    }
  });

  if (this.companyForm.valid) {
    -----------------
    -----------------
  }
}

My problem is it was saying .forEach is not a function. Can anyone please explain me whats wrong in the code. Any help would be appreciated. Thanks.


Solution

  • This is actually a linting issue, typescript and the editor complains about this because a formInstance.get('controlName') returns an Abstract control. You will have to tell the them that the control you received is a FormArray, you can do this by doing:

    this.ip_addresses_arr = this.companyForm.get('company_ip_addresses') as FormArray;
    

    And you need to loop over the controls as.

    this.ip_addresses_arr.controls.forEach()
    

    And you are not accessing the controls correctly

    saveCompanyInfo() {
      this.ip_addresses_arr = this.companyForm.get('company_ip_addresses') as FormArray;
      this.ip_addresses_arr.controls.forEach(eachfield => {
        if(eachfield.get('start_ip').value != "" && eachfield.get('end_ip').value == ""){
          console.log("coming inside end_ip is empty");
          eachfield.get('end_ip').setErrors({'incorrect': true});
          eachfield.get('end_ip').markAsTouched();
        }else if(eachfield.get('end_ip').value != "" && eachfield.get('start_ip').value == ""){
          console.log("coming inside start_ip is empty");
          eachfield.get('start_ip').setErrors({'incorrect': true});
          eachfield.get('start_ip').markAsTouched();
        }else{
          eachfield.get('start_ip').setErrors(null);
          eachfield.get('end_ip').setErrors(null);
        }
      });
      }