Angular 2: formGroup expects a FormGroup instance. Please pass one in

FormsAngular

Forms Problem Overview


I am creating a form in Angular 2. My goal is to get data from the API and pass it into the form for editing purposes. However, I am running into this error:

> EXCEPTION: Uncaught (in promise): Error: Error in ./EditPatientComponent class EditPatientComponent - inline template:1:10 caused by: formGroup expects a FormGroup instance. Please pass one in.

Here is the current code with the error.

html

<section class="CreatePatient">
    <form [formGroup]="patientForm" (ngSubmit)="onSubmit()">
        <div class="row">
            <div class="form-group col-12 col-lg-3">
                <label for="firstName">First Name</label>
                <input formControlName="firstName" type="text" class="form-control" id="firstName" >
            </div>
        
        <div class="row">
            <div class="col-12 col-lg-2">
                <button type="submit" name="submit" class="btn btn-block btn-primary">Save</button>
            </div>
        </div>
    </form>
</section>

ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { FormBuilder, FormGroup, FormControl } from '@angular/forms';

import { PatientService } from './patient.service';
import { Patient } from './patient';

@Component({
    templateUrl: 'editpatient.component.html'
})
export class EditPatientComponent implements OnInit {
    errorMessage: string;
    id: string;
    editMode = true;
    private patientForm: FormGroup;
    private patient: Patient;

    constructor(
        private patientService: PatientService,
        private router: Router,
        private activatedRoute: ActivatedRoute,
        private formBuilder: FormBuilder) {

        console.log("routes");
        console.log(activatedRoute.snapshot.url[1].path);
    }

    ngOnInit() {
        this.getPatient();
    }

    getPatient() {
            this.patientService.getPatient(this.activatedRoute.snapshot.url[1].path)
            .subscribe(
                patient => {
                    this.id = this.activatedRoute.snapshot.url[1].path;
                    this.patient = patient;
                    this.initForm();
                },
                error =>  this.errorMessage = <any>error);

    }

    onSubmit(form){
        console.log(this.patientForm);
        // Post the API
    };

    initForm() {
        let patientFirstName = '';

        if (this.editMode) {
            console.log(this.patient.firstName);
            console.log(this.patient.lastName);
            console.log(this.patient.participantUuid);
            patientFirstName = this.patient.firstName;
        }

        this.patientForm = new FormGroup({
            'firstName': new FormControl(patientFirstName)
        })
    };

}

Any help/pointing me in the right direction would be great! Thanks!

Forms Solutions


Solution 1 - Forms

Your patientForm is undefined until the patient in the subscription is populated. As such, you're trying to bind to a value that doesn't exist in the template at the time the template is parsed.

Add an *ngIf to render the form only when patient is truthy, or the form group is instantiated:

<section class="CreatePatient">
    <form *ngIf="patient" [formGroup]="patientForm" (ngSubmit)="onSubmit()">
        <div class="row">
            <div class="form-group col-12 col-lg-3">
                <label for="firstName">First Name</label>
                <input formControlName="firstName" type="text" class="form-control" id="firstName" >
            </div>

        <div class="row">
            <div class="col-12 col-lg-2">
                <button type="submit" name="submit" class="btn btn-block btn-primary">Save</button>
            </div>
        </div>
    </form>
</section>

When the patient is populated in the subscription, the patientForm instance will exist and the binding will work. It's a common "gotcha" when dealing with async values.

Forms don't always have starting values, so you can also check for the existence of the form itself:

<form *ngIf="patientForm" [formGroup]="patientForm" (ngSubmit)="onSubmit()">

The important part is that the form isn't rendered until its instantiated.

Solution 2 - Forms

Problem is that your form is null on the beginning.

And only on ng init you will get patient and then create it. You should initialize your form on the begining or

<section class="CreatePatient" *ngIf="patientForm">

Solution 3 - Forms

Guys who face issues with reactive forms First in your component.ts file make sure you import the following:

import { FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';

export class NewsfeedformComponent implements OnInit {

NewsfeedForm: FormGroup;
constructor(private _formBuilder: FormBuilder){}

 ngOnInit() {

this.lookupService.getStatus().subscribe((status: IStatus) => {
  this.status = status;
});

this.NewsfeedForm = this._formBuilder.group({
  NewsfeedID: [0,null],
  StatusID: ['', Validators.required],
  publishdate: ['', Validators.required]
  })
 }

}

in your component html file

             <form class="form-container" [formGroup]="NewsfeedForm" 
#newsFeedform="ngForm" (ngSubmit)="form1()">

 <div id="rowTwo" fxLayout="row" fxLayout.lt-md="column" fxLayoutGap="20px" fxLayoutGap.lt-md="0px">
                <mat-form-field appearance="outline">
                    <mat-label>Status</mat-label>
                    <mat-select formControlName="StatusID" required>
                        <mat-option></mat-option>
                        <mat-option *ngFor="let itemofStatus of status" [value]="itemofStatus.StatusID">
                            {{itemofStatus.Status}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>

                <mat-form-field appearance="outline">
                    <input matInput [matDatepicker]="publishdate" placeholder="Publish Date"
                        formControlName="publishdate">
                    <mat-datepicker-toggle matSuffix [for]="publishdate"></mat-datepicker-toggle>
                    <mat-datepicker #publishdate></mat-datepicker>
                </mat-form-field>
            </div>

Solution 4 - Forms

I have received the same error, initialize error, but it was the result of a typo.

Instead of typing ngOnInit, I wrote ngOninit (must be capital I)

but the error was same, group initialization, it's difficult to time the solution for these kinds of typo error, so I thought this might be useful for others in the future.

Solution 5 - Forms

This issue can happen when the FormGroup is not initialized. Please add *ngIf="patientForm" on form tag.

<i><form [formGroup]="loginForm" *ngIf="patientForm" (ngSubmit)="onSubmit()"></i>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJessySueView Question on Stackoverflow
Solution 1 - FormsBrandon TaylorView Answer on Stackoverflow
Solution 2 - FormsVova BilyachatView Answer on Stackoverflow
Solution 3 - FormsMJ XView Answer on Stackoverflow
Solution 4 - FormsAdhi VenkateshView Answer on Stackoverflow
Solution 5 - FormsShalim AhmedView Answer on Stackoverflow