141

How can I add a FormControl to a FormGroup dynamically in Angular?

For example, I would like to add a mandatory control which name is "new" and its default value is ''.

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
joeSmith
  • 1,445
  • 2
  • 8
  • 7
  • 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:01
  • Like Siro answered your question, you can use addControl method to add new inputs to your form group. I have a little project wich studied dynamic forms. I hope which be useful. https://stackblitz.com/edit/angular-eypxbq?embed=1&file=src/app/app.component.html – Michael Charles Apr 30 '19 at 21:19

7 Answers7

289

addControl is what you need. Please note the second parameters must be a FormControl instance like so:

this.testForm.addControl('new', new FormControl('', Validators.required));

You can also add the validators dynamically if you want with the setValidators method. Calling this overwrites any existing sync validators.

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Siro
  • 3,179
  • 1
  • 10
  • 10
  • Sorry, how do to includo more that one validator, for example this.testForm.addControl('new', new FormControl('', [Validators.required, Validators.max(100)]); – Miguel Navas May 27 '21 at 13:02
  • Works like a charm. – Ali Celebi Oct 13 '21 at 15:39
  • For me I needed to add formGroup: FormGroup to the type in order for this to work in Angular 14. –  Jul 08 '22 at 13:27
  • Note that you can add several validators using an array: `this.testForm.addControl('name', new FormControl('', [Validators.required, Validators.max(5)]))` – A.Casanova Oct 18 '22 at 07:31
65

If you are using FormBuilder for your form, you can also use that for adding a control:

constructor(private fb: FormBuilder) { }
    
method() {
  this.testForm.addControl('new', this.fb.control('', Validators.required));
}
HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
AT82
  • 71,416
  • 24
  • 140
  • 167
9

simple use:

  this.testForm.addControl('new', this.fb.group({
      name: ['', Validators.required]
    }));
Trilok Singh
  • 1,227
  • 12
  • 10
4

Angular 14 added typings to forms. Here is what the new syntax looks like:

Form declaration

public form = new FormGroup<{ new?: FormControl<string | null> }>();

Note that the new control must be declared as optional. You won't be able to use addControl if the field isn't declared first.

For a bigger form you can use an interface:

interface MyForm {
    field1: FormControl<string | null>;
    field2: FormControl<string | null>;
    new?: FormControl<string | null>;
}

public form = new FormGroup<MyForm>({
    field1: new FormControl<string | null>('', Validators.required),
    field2: new FormControl<string | null>('', Validators.required),
});

Add control to the form

this.form.addControl('new', new FormControl<string | null>('', Validators.required));
Carrm
  • 1,485
  • 3
  • 24
  • 45
3
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@Component({
  selector: 'app-component-name',
  templateUrl: './component-name.component.html',
  styleUrls: ['./component-name.component.scss']
})
export class ComponentName implements OnInit {

    formGroup: FormGroup;        
    constructor(private formBuilder: FormBuilder) {}

    ngOnInit() {
       this.formGroup = this.formBuilder.group({
        firstName: new FormControl('', Validators.required),
        lastName:  new FormControl('', Validators.required),
      });    
    }
    
    // Add single or multiple controls here
    addNewControls(): void {
      this.formGroup = this.formBuilder.group({
         ...this.formGroup.controls,
         email: ['', Validators.required],
         phone: ['', Validators.required]
      });
    }
}
ImFarhad
  • 2,669
  • 2
  • 18
  • 30
2

I was facing the same problem in Angular 12. Following code snippets worked perfectly for me.

Declare the form:

public form: FormGroup;

Create a new control for the form:

this.form.addControl('new', new FormControl('', Validators.required));
Chamila Maddumage
  • 3,304
  • 2
  • 32
  • 43
  • 2
    This answer worked for me since Angular 14 now made the form groups require types. –  Jul 08 '22 at 13:28
1

To add a new FormControl dynamically to only one instance of an existing FormArray, use the casting technique.

form: FormGroup;

constructor(private fb: FormBuilder){
  this.form = this.fb.group({
    formArrayName: this.fb.array([])
  });
} //

addNewFormArrayInstance(insertIndex: number){
  // insertIndex to insert at a specific position
  const NEWFORMGROUP = new FormGroup({
    'control1': new FormControl(''),
    'control2': new FormControl({value: [], disabled: true}),
    'control3': new FormControl('', Validators.required),
    'control4': new FormControl(true)
  });

  // use push(NEWFORMGROUP) if needed
  (<FormArray>this.form.get('formArrayName')).insert(insertIndex, NEWFORMGROUP);
} //

addControlToFormArrayInstance(index: number){
  // index is the FormArray instance's index to which a new control is to be added
  (<FormGroup>
    (<FormArray>this.form.get('formArrayName')).controls[index]
  ).addControls(
    'newControl', new FormControl('new')
  );
} //
Prakash M.
  • 479
  • 8
  • 26