2
votes

I have one this basic form in Angular 5, however this being released the following error.

Here is the error:

EditVisitanteDialogComponent.html:10 ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

Example:

> 
> <div [formGroup]="myGroup">   <input formControlName="firstName">
> </div>
> 
> In your class:

this.myGroup = new FormGroup({ firstName: new FormControl() }); at Function.ReactiveErrors.missingFormException (forms.js:6347) at FormGroupDirective._checkFormPresent (forms.js:6852) at FormGroupDirective.ngOnChanges (forms.js:6623) at checkAndUpdateDirectiveInline (core.js:12358) at checkAndUpdateNodeInline (core.js:13886) at checkAndUpdateNode (core.js:13829) at debugCheckAndUpdateNode (core.js:14722) at debugCheckDirectivesFn (core.js:14663) at Object.eval [as updateDirectives] (EditVisitanteDialogComponent.html:10) at Object.debugUpdateDirectives [as updateDirectives] (core.js:14648) View_EditVisitanteDialogComponent_0 @ EditVisitanteDialogComponent.html:10

component.html

<div class="dialog-content-wrapper">
    <mat-toolbar matDialogTitle class="mat-accent m-0">
        <mat-toolbar-row fxLayout="row" fxLayoutAlign="space-between center">
            <span class="title dialog-title">Editar visitante</span>
            <button mat-button class="mat-icon-button" (click)="dialogRef.close()" aria-label="Close dialog">
                <mat-icon>close</mat-icon>
            </button>
        </mat-toolbar-row>
    </mat-toolbar>
   //esta linha que esta com o erro 
    <form name="form" [formGroup]="editForm" #f="ngForm">
        <div mat-dialog-content class="m-0 p-24" fusePerfectScrollbar>
            <div fxLayout="row" fxLayoutAlign="start start">
                <mat-icon class="mr-12 mt-12">label_outline</mat-icon>
                <mat-form-field class="mr-16">
                    <mat-select placeholder="Documento" formControlName="documento">
                        <mat-option value="option">Option</mat-option>
                    </mat-select>
                </mat-form-field>
                <mat-form-field>
                    <input matInput placeholder="Número" formControlName="numDocumento">
                </mat-form-field>
            </div>

            <div fxLayout="row" fxLayoutAlign="start start">
                <mat-icon class="mr-12 mt-12">account_circle</mat-icon>
                <mat-form-field fxFlex>
                    <input formControlName="nome" placeholder="Nome do Visitante" matInput required>
                </mat-form-field>
            </div>

            <div fxLayout="row" fxLayoutAlign="start start">
                <mat-icon class="mr-12 mt-12">group</mat-icon>
                <mat-form-field fxFlex>
                    <mat-select placeholder="Intenção" formControlName="motivoVisita">
                        <mat-option value="option">Familiar</mat-option>
                        <mat-option value="option">Particular</mat-option>
                        <mat-option value="option">Prestado de Serviço</mat-option>
                    </mat-select>
                </mat-form-field>
            </div>

            <div fxLayout="row" fxLayoutAlign="start start">
                <mat-icon class="mr-12 mt-12">lock_open</mat-icon>
                <mat-form-field fxFlex>
                    <mat-select placeholder="Autorização" formControlName="tipoAutorizacao">
                        <mat-option value="option">Lorem ipsum...</mat-option>
                    </mat-select>
                </mat-form-field>
            </div>

            <div fxLayout="row" fxLayoutAlign="start start">
                <div fxLayout="column">
                    <p>Quando?</p>
                    <mat-radio-group formControlName="periodoAutorizacao">
                        <mat-radio-button value="hoje">Hoje</mat-radio-button>
                        <mat-radio-button value="semanal" class="ml-8">Semanal</mat-radio-button>
                        <mat-radio-button value="periodo" class="ml-8">Período</mat-radio-button>
                    </mat-radio-group>

                    <div id="periodo" fxLayout="row" fxLayoutAlign="space-evenly start">
                        <mat-form-field fxFlex="45">
                            <input matInput [matDatepicker]="picker" placeholder="De" formControlName="periodoDe">
                            <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
                            <mat-datepicker #picker></mat-datepicker>
                        </mat-form-field>
                        <mat-form-field fxFlex="45">
                            <input matInput [matDatepicker]="myDatepicker" placeholder="Até" formControlName="periodoAte">
                            <mat-datepicker-toggle matSuffix [for]="myDatepicker"></mat-datepicker-toggle>
                            <mat-datepicker #myDatepicker></mat-datepicker>
                        </mat-form-field>
                    </div>

                    <div id="semanal">
                        <mat-checkbox formControlName="diaSem1">Seg</mat-checkbox>
                        <mat-checkbox formControlName="diaSem2">Ter</mat-checkbox>
                        <mat-checkbox formControlName="diaSem3">Qua</mat-checkbox>
                        <mat-checkbox formControlName="diaSem4">Qui</mat-checkbox>
                        <mat-checkbox formControlName="diaSem5">Sex</mat-checkbox>
                        <mat-checkbox formControlName="diaSem6">Sáb</mat-checkbox>
                        <mat-checkbox formControlName="diaSem7">Dom</mat-checkbox>
                    </div>
                </div>
            </div>

            <div>
                <mat-form-field fxFlex>
                    <textarea matInput placeholder="Observação" formControlName="observacao"></textarea>
                </mat-form-field>
            </div>


        </div>
        <div mat-dialog-actions class="m-0 p-16" fxLayout="row" fxLayoutAlign="space-between center">
            <button mat-raised-button class="save-button mat-accent" aria-label="SAVE">
                SALVAR
            </button>

            <button mat-button class="mat-icon-button" aria-label="Delete" matTooltip="Excluir">
                <mat-icon>delete</mat-icon>
            </button>

        </div>
    </form>
</div>

component.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'editvisitante',
  templateUrl: './editvisitante.component.html',
  styleUrls: ['./editvisitante.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class EditvisitanteComponent implements OnInit {

  editForm: FormGroup;

  constructor(private formBuilder: FormBuilder) {
  }

  ngOnInit() {

    this.editForm = this.formBuilder.group({
       documento: ["", Validators.required],
       numDocumento: ["", Validators.required],
       nome: ["", Validators.required],
       motivoVisita: ["", Validators.required],
       tipoAutorizacao: ["", Validators.required],
       periodoAutorizacao: ["", Validators.required],
       periodoDe: [""],
       periodoAte: [""],
       diaSem1: [""],
       diaSem2: [""],
       diaSem3: [""],
       diaSem4: [""],
       diaSem5: [""],
       diaSem6: [""],
       diaSem7: [""],
       observacao: ["", Validators.required],
    });

  }

}
2

2 Answers

1
votes

I've come across this problem as well. It seems like for some reason, the HTML is being processed before the FormGroup, even if it's in the Constructor or ngOnInit. What fixed my error was wrapping it in a TimeOut, although I'm not sure if that's the best or cleanest solution.

setTimeout(() => {
  this.editForm = this.formBuilder.group({
     documento: ["", Validators.required],
     numDocumento: ["", Validators.required],
     nome: ["", Validators.required],
     motivoVisita: ["", Validators.required],
     tipoAutorizacao: ["", Validators.required],
     periodoAutorizacao: ["", Validators.required],
     periodoDe: [""],
     periodoAte: [""],
     diaSem1: [""],
     diaSem2: [""],
     diaSem3: [""],
     diaSem4: [""],
     diaSem5: [""],
     diaSem6: [""],
     diaSem7: [""],
     observacao: ["", Validators.required],
  });
), 1);
2
votes

if this happened to anyone in newer versions of angular, this could be the cause of this ->
if your ngOnInit is async method u must first initialize your form group before u await any other async method or some asynchronous code

async ngOnInit() {
this.signinForm = new FormGroup({
  email: new FormControl("", [Validators.required, Validators.email]),
  password: new FormControl("", [
    Validators.required,
    Validators.pattern("^[a-zA-Z0-9]*"),
  ]),
});

///... other async code

}