Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reactive Forms: How to add new FormGroup or FormArray into an existing FormGroup at a later point in time in Angular 7/8/9

In the other examples at StackOverflow there are many questions about using FormGroups in FormArrays. But my question is the opposite.

FormArrays have a push method, that makes many things possible. FormGroups have indeed an addControl method for adding simple FormControls. AFAIK FormGroups do not have addFormArray or addFormGroup method. Therefore I need your help.

Following situation:

this.myForm = this.fb.group({
  id: this.fb.control([this.book.id]),
  // or short form `id: [this.book.id],`
});

Adding a simple control at a later point in time is easy:

this.myForm.addControl('isbn', this.fb.control(this.book.isbn));

But what about adding FormArrays and FormGroups into an existing FormGroup? For instance, I would like to use the following array and object for this purpose:

const authors  = ['George Michael', 'Aretha Franklin'];
const metaData = { description : 'Great Book', publication: 2019}

I would like to add authorsArray or metaData only then if they are existing. That's the reason, why I want to add them at a later time.

p.s. Please ignore the validation rules.

like image 525
Lonely Avatar asked Mar 25 '19 09:03

Lonely


People also ask

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.

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.


2 Answers

FormGroup addControl method accepts AbstractControl as parameter which can be either a FormControl or a FormArray or another FormGroup as they all extend AbstractControl.

class FormGroup extends AbstractControl {}

class FormControl extends AbstractControl {}

class FormArray extends AbstractControl {}

FormBuilder can help you building such controls with array() and group() methods:

this.myForm = this.fb.group({
  id: this.fb.control([this.book.id]),
  authors: this.fb.array(['George Michael', 'Aretha Franklin']),
  metaData: this.fb.group({ description : 'Great Book', publication: 2019})
});

You still can use the factory afterwards to build the controls you need (no matter what kind of control it is):

this.myForm.addControl('authors',
                       this.fb.array(['George Michael', 'Aretha Franklin']))
this.myForm.addControl('metaData',
                       this.fb.group({description: 'Great Book', publication: 2019}))
like image 200
Grégory Elhaimer Avatar answered Oct 30 '22 04:10

Grégory Elhaimer


You can simply pass the FormArray instead of a FormControl.

this.form.addControl('arr',this.fb.array([]));

Edit: To use existing value

To use the value from the authors array, use this:

authors.forEach(author => {
  (<FormArray>this.form.controls.arr).push(new FormControl(author));
});

OR

this.myForm.addControl('authors', this.fb.array(['George Michael', 'Aretha Franklin']))

like image 28
Sachin Gupta Avatar answered Oct 30 '22 05:10

Sachin Gupta