Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add a FormGroup to a FormArray without triggering form change event

Tags:

angular

I initialise a form with any empty array in definitionProperties how can I update FormGroup? I need to do so without triggering a change event otherwise it causes an infinite loop in the valueChanges observable.

this.gridProcessorForm = this.fb.group({
    propertiesSide: new FormControl(),
    objectNamesSide: new FormControl(),
    definitionProperties: this.fb.array([])
});

This causes the infinite loop:

this.gridProcessorForm.valueChanges.subscribe(val => {
    let propertyGroups: FormGroup[] = [];
    for (let property of this.objectDefinition.properties) {
      let group = this.createPropertyFormGroup(property);
      (this.gridProcessorForm.get('definitionProperties') as FormArray).push(group); // triggers change event so infinite loop
    }
});

When using setValue with { emitEvent: false } to overwrite the FormArray it gets an error.

this.gridProcessorForm.valueChanges.subscribe(val => {
  if (this.gridSideSelection = 'top') {        
    let propertyGroups: FormGroup[] = [];
    for (let property of this.objectDefinition.properties) {
      let group = this.createPropertyFormGroup(property);
      propertyGroups.push(group);
    }

    (this.gridProcessorForm.get('definitionProperties') as FormArray).setValue(propertyGroups, { emitEvent: false });
  }
});

I get this error:

There are no form controls registered with this array yet. 

It seems it requires the form builder to initialise with a group in the FormArray? But I want to initialise the form with everything empty.

like image 648
doe Avatar asked Oct 21 '19 06:10

doe


People also ask

Can FormArray contains FormGroup?

The FormArray is a way to Manage collection of Form controls in Angular. The controls can be FormGroup, FormControl, or another FormArray. Because it is implemented as Array, it makes it easier dynamically add controls.

How do I use FormGroup in FormArray?

We do not have a name to the FormGroup . The Index of the element is automatically assigned as the name for the element. Hence we use the [formGroupName]="i" where i is the index of the FormArray to bind the FormGroup to the div element. Finally, we add the controls using the formControlName directive.

What is the difference between FormGroup and FormArray?

Whereas FormGroup represents an entire form or a fixed subset of a form's fields, FormArray usually represents a collection of form controls that can grow or shrink.


2 Answers

There's an issue in angular's repo. Please refer this comment https://github.com/angular/angular/issues/23336#issuecomment-543209703

Basically, you need to do it like this:

const addedControl = new FormControl();
this.controlArray.controls.push(addedControl);
this.controlArray['_registerControl'](addedControl);

UPDATE 05.2021

This was fixed in Angular v12 https://github.com/angular/angular/issues/20439#issuecomment-779988084

like image 119
cuddlemeister Avatar answered Oct 17 '22 08:10

cuddlemeister


I hope this will help as this is my running code.

    let containersArray = <FormArray>this.formName.controls['containers'];
    containersArray.push(this.addContainerInitialize(container));


addContainerInitialize(value) {

    return this.fb.group({
        containerNumber: [value.containerNumber],
        conType: [value.conType, Validators.required],
        quantity: [value.noOfContainers, Validators.required],
        weight: [value.grossWeight, Validators.required]
    });
}
like image 39
MaBbKhawaja Avatar answered Oct 17 '22 09:10

MaBbKhawaja