157

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 ''.

2

7 Answers 7

309

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Sorry, how do to includo more that one validator, for example this.testForm.addControl('new', new FormControl('', [Validators.required, Validators.max(100)]);
Works like a charm.
For me I needed to add formGroup: FormGroup to the type in order for this to work in Angular 14.
Note that you can add several validators using an array: this.testForm.addControl('name', new FormControl('', [Validators.required, Validators.max(5)]))
71

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));
}

1 Comment

how to stop event emit when adding control inside a value change subscription?
11

simple use:

  this.testForm.addControl('new', this.fb.group({
      name: ['', Validators.required]
    }));

Comments

6

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));

Comments

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]
      });
    }
}

Comments

3

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));

1 Comment

This answer worked for me since Angular 14 now made the form groups require types.
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')
  );
} //

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.