14

I am using the latest version of Angular (v6.0.5).

I have a FormGroup consisting of 3 common controls and based on some logic i want to add other multiple controls to the same FormGroup.

I know i can use this.form.addControl() but i dont want to do this for each individual form control

Is there an easy way to do this?

Example:

this.form = this.formBuilder.group({
    'id': new FormControl('', Validators.required),
    'firstName' new FormControl('', Validators.required),
    'lastName' new FormControl('', Validators.required)
});

if (blah) {
    // Append more FormControls here to same FormGroup
    this.form.addControl('houseNumber', new FormControl(''));
    this.form.addControl('street', new FormControl(''));
    this.form.addControl('postCode', new FormControl(''));
}
S edwards
  • 163
  • 1
  • 1
  • 8
  • 3
    `['houseNumber', 'street', 'postCode'].forEach(x => this.form.addControl(x, new FormControl(''))` – yurzui Jun 18 '18 at 11:57
  • @yurzui I can only add 1 control at a time, my question is, is there a way to add multiple at the same time? – S edwards Jun 18 '18 at 11:59
  • With my code above you can add several controls – yurzui Jun 18 '18 at 12:01
  • The only issue i have with this is i need to set the value to something different for each control other than `''` – S edwards Jun 18 '18 at 12:04
  • 1
    You can have a map like `{ houseNumber: 'val1', street: 'val2...}` – yurzui Jun 18 '18 at 12:05
  • See also https://github.com/angular/angular/issues/12747#issuecomment-259835873 – yurzui Jun 18 '18 at 12:07
  • that could also help: https://stackoverflow.com/questions/55334283/reactive-forms-how-to-add-new-formgroup-or-formarray-into-an-existing-formgroup –  Mar 25 '19 at 12:02

2 Answers2

13

For some reason Angular didn't provide API for that case.

You can simply loop over your controls and add it to FormGroup or you can build new FormGroup based on existing:

this.form = this.formBuilder.group({
  'id': new FormControl('', Validators.required),
  'firstName': new FormControl('', Validators.required),
  'lastName': new FormControl('', Validators.required)
});

let blah = true;

if (blah) {
  this.form = this.formBuilder.group({
    ...this.form.controls,
    'houseNumber': new FormControl(''),
    'street': new FormControl('')
  });
} else {
  this.form = this.formBuilder.group({
    ...this.form.controls,
    'otherControl': new FormControl(''),
    'otherControl2': new FormControl(''),
    'otherControl3': new FormControl('')
  });
}

Ng-run Example

yurzui
  • 205,937
  • 32
  • 433
  • 399
4

If you don't want to delay the form creation you can simply do something like that:

// You can write this sugar, you don't have to write new FormControl
const form = {
    id: ['', Validators.required],
    firstName: ['', Validators.required],
    lastName: ['', Validators.required]
};

if (blah) {
    form.someField: ['', Validators.required];
} else {
    form.someotherField: ['', Validators.required];
}

this.form = this.formBuilder.group(form);

Or this shorter inline version:

this.form = this.formBuilder.group({
    id: ['', Validators.required],
    firstName: ['', Validators.required],
    lastName: ['', Validators.required],
    ...(blah ? {form.someField: ['', Validators.required]} : {form.someotherField: ['', Validators.required]})
});
Alexandre Annic
  • 9,942
  • 5
  • 36
  • 50