Understanding Angular FormBuilder with Groups and ngModel data and how/if they can be used together?


I am running into some issues with trying to use FormBuilder in my Angular app and how I can set the default values in the form based on my ngModel data.

In my class, I have the following code:

form: FormGroup;

    private fb: FormBuilder,
) { }

ngOnInit() {

    this.form = this.fb.group({
        category: ['', [Validators.required]],
        quantity: [1, [Validators.required]],
        size: ['', [Validators.required]],
        title: ['', [Validators.required]],

When I look at the {{ form.value | json }} in my template, it shows the original values with the empty values. So I decided to try to set the default values in the FormBuilder group like this:

    this.form = this.fb.group({
        category: [this.item.category, [Validators.required]],
        quantity: [this.item.quantity, [Validators.required]],
        size: [this.item.size, [Validators.required]],
        title: [this.item.title, [Validators.required]],

But I am given these errors:

ERROR Error: formGroup expects a FormGroup instance. 
ERROR TypeError: Cannot read properties of undefined (reading 'category')
ERROR TypeError: Cannot read properties of undefined (reading 'value')

This is my template for the form:

<form [formGroup]="form">
        <ion-item lines="none">
            <ion-label position="stacked">Category</ion-label>
            <ion-select [(ngModel)]="item.category" [ngModelOptions]="{standalone: true}">
                <ion-select-option *ngFor="let category of categories" [value]="category">
                    {{ category }}

        <ion-item lines="none">
            <ion-label position="stacked">Title</ion-label>
            <ion-input [(ngModel)]="item.title" [ngModelOptions]="{standalone: true}"></ion-input>

        <ion-item lines="none">
            <ion-label position="stacked">Size</ion-label>
            <ion-input [(ngModel)]="item.size" [ngModelOptions]="{standalone: true}"></ion-input>

        <ion-item lines="none">
            <ion-label position="stacked">Quantity</ion-label>
            <ion-input type="number" [(ngModel)]="item.quantity" [ngModelOptions]="{standalone: true}"></ion-input>


Any thoughts what is wrong with my approach and how I can get the default values from my this.item to appear in the form?


Zerospi, the problem is that you create the form before you has data in your variable "item" – this is the reason you don’t see the value

  1. NEVER Mix together Reactive forms and Template-Driven (ngModel)

    The use [(ngModel)]="variable" [ngModelOptions]="{standalone: true} it’s ONLY to get an input that not belong to the FormGroup.

    e.g you can has a "checkbox" to show a new input. Some like

     form=new FormGroup({
       phone:new FormControl()
       mobile:new FormControl()
     <form [formGroup]="form">
       Phone<input formControlName="phone">
       <input type="checkbox" [(ngModel)]="movil" 
       <input *ngIf="movil" formControlName="mobile">

    Well, really we use

       <input type="checkbox" [ngModel]="movil" 
               (ngModelChange)="movil=$event;!$event && form.get('mobile').setValue('')

    To "clean" the FormControl "mobile" if we uncheck

    How control a FormGroup?

  2. In general we can have a function in the way

       data=data || {phone:'',mobile:''}
       return this.fb.group({

    And use

    this.form=this.getFormGroup(this.item) //if we have an object "this.item"
    this.form=this.getFormGroup() //if we want an empty Form
  3. Another approach is create the form an use patchValue()

  4. To avoid initial errors (e.g. we create the form after a call to an API), sometimes is util use some like

    <form *ngIf="form" [formGroup]="form">
  5. Remember that a FormControl is disabled, don’t showed in form.value, you need use form.getRawValue()

Answered By – Eliseo

Answer Checked By – Cary Denson (AngularFixing Admin)

Leave a Reply

Your email address will not be published.