10

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.

Nikita Fedyashev
  • 15,938
  • 11
  • 41
  • 69
Lonely
  • 5,174
  • 6
  • 33
  • 67
  • Hello. You add your FormGroups and FormArrays just you added your FormControl. – MullisS Mar 25 '19 at 09:05
  • `registerControl` might work as well. Both of these functions take an AbstractControl as an arguement. FormGroup extends AbstractControl so this should work for FormGroups as well. – Joey Gough Mar 25 '19 at 09:05
  • You might want look at this answer of mine. Hope it helps: https://stackoverflow.com/questions/49666593/add-item-in-dynamic-reactive-form-in-angular/49667898#49667898 – Swoox Mar 25 '19 at 09:21

2 Answers2

9

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}))
Nikita Fedyashev
  • 15,938
  • 11
  • 41
  • 69
Grégory Elhaimer
  • 2,341
  • 1
  • 12
  • 19
2

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']))

Sachin Gupta
  • 3,755
  • 2
  • 13
  • 29