Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

forms

angular

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!

like image 233
JessySue Avatar asked Apr 27 '17 23:04

JessySue


People also ask

How do I add a control to a FormGroup?

To add, update, or remove controls in FormGroup , use the following commands: addControl() adds a control and updates its value and validity. removeControl() removes a control. setControl() replaces an existing control.

Can't bind to FormGroup since it isn't a known property of?

Angular is trying to tell us that it doesn't know about the formGroup directive on the <form> element in your component. This usually happens when the wrong forms module is imported, the right module is imported in the wrong place or the ReactiveFormsModule is just not imported at all.

How do you initialize a FormGroup?

Using FormGroup Next, you need to create an instance of FormGroup with the instances of FormControl : productForm = new FormGroup({ reference: new FormControl(), quantity: new FormControl('11') }); You can provide a default value for the control, by passing it as an argument to the FormControl .

What is FormGroup instance?

Descriptionlink. A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key.


2 Answers

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.

like image 175
Brandon Avatar answered Sep 24 '22 09:09

Brandon


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"> 
like image 22
Vova Bilyachat Avatar answered Sep 22 '22 09:09

Vova Bilyachat