How to add FormControl dynamically to FormGroup in angular 5?

16,226

You have a couple of issues: 1. you push new row to controls of FormArray other than FormArray itself

this.entries.controls.push(this.fb.group(row));

should be

this.entries.push(this.fb.group(row));

2. don't create new FormArray everytime and reload every single row when invoke createFormControls(), you can access it by your get entries() method

Solution 1:

Check length of entries, if it is 0, initialize it with rows otherwise just push last row into the existing FormArray

createFormControls() {
        const keys = Object.keys(this.entries.value);
        if( keys.length === 0) {
          this.rows.forEach(row => {
              this.entries.push(this.fb.group(row));
          });
        } else {
          const row = this.rows[this.rows.length - 1];
          this.entries.push(this.fb.group(row));
        }
    }

Solution 2:

Personally, I prefer putting createFormArray() and appendTo() or popFrom() into the parent Component. It is clean and easy read. We don't need ChangeDetectionRef in this case.

I have moved createFormControls() from form-table component to dummy component and rename it to createFormArray() and changed addNewRow() a little bit, now everything works properly

// create FormArray once
createFormArray() {
    const elements: any[] =[];

    this.rows.forEach(row => {
        elements.push(this.fb.group(row));
    });
    return this.fb.array(elements);
}

addNewRow() {
  const newRow =    {
            name: 'NAFFD',
            age: 12,
            place: 'TN'
        };

    this.rows.push(newRow);  // update rows

    const persons =  this.dummyForm.get('persons') as FormArray;
    persons.push(this.fb.group(newRow));  // update FormArray
}

When initializing your dummy form, do below:

   this.dummyForm = this.fb.group({
        persons: this.createFormArray(),
        store: this.fb.group({
            branch: '',
            code: ''
        })
    });

enter image description here

Hope it helps and happy coding!

Share:
16,226
Manoj
Author by

Manoj

Updated on June 17, 2022

Comments

  • Manoj
    Manoj almost 2 years

    I am trying to build a data-table compatible with FormGroup & FormArray. I will pass header details and rows to this component with parentForm group.

    I have created a small add button, on clicking it, I will add new items dynamically. In this case, UI is updating fine, but if I print formGroup.value(), I am getting only the initial value passed. Not the updated formControl. I'm not sure what I am missing.

    export class FormTableComponent implements OnChanges {
        @Input() headers: Array<string>;
        @Input() rows: Array<any>;
        @Input() parentFG: FormGroup;
        @Input() entriesName: string;
    
        get entries(): FormArray {
            return <FormArray>this.parentFG.get(this.entriesName);
        }
    
        constructor(private fb: FormBuilder, private cd: ChangeDetectorRef) {}
    
        ngOnChanges() {
            this.createFormControls();
        }
    
        createFormControls() {
            this.parentFG.controls[this.entriesName] = this.fb.array([]);
            this.rows.forEach(row => {
                this.entries.controls.push(this.fb.group(row));
            });
        }
    }
    

    DEMO

  • Manoj
    Manoj over 6 years
    Yes, if you see my code, I am already creating new array and sending like you said above. It doesn't helps.