HTML CODE:
<div class="row">
<div class="col-xs-12">
<form [formGroup]="recipeForm" (ngSubmit)="onSubmit()" >
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-success" [disabled]="!recipeForm.valid">Save</button>
<button type="button" class="btn btn-danger" (click)="onCancel()">Cancel</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="name">Name</label>
<input
type="text"
id="name"
[formControlName]="'name'"
class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="ImagePath">ImageUrl</label>
<input
type="text"
id="ImagePath"
class="form-control"
[formControlName]="'imagePath'"
#imagePath>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<img src="imagePath.value" class="img-responsive" >
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="description">Description</label>
<textarea
type="text"
id="description"
[formControlName]="'description'"
class="form-control"
rows="6"></textarea>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12" formArrayName="ingredients">
<div class="row"
*ngFor="let ingredientCtrl of
controls; let i=index"
[formGroupName]="i"
style="margin-top:10px;">
<div class="col-xs-8">
<input
type="text"
class="form-control"
[formControlName]="'name'">
</div>
<div class="col-xs-2">
<input
type="number"
class="form-control"
[formControlName]="'amount'">
</div>
<div class="col-xs-2">
<button
type="button"
class="btn btn-danger" (click)="onDeleteIngredient(i)">X</button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button
type="button"
class="btn btn-success"
(click)="onAddIngredient()">Add Ingredients</button>
</div>
</div>
</div>
</div>
</form>
MY.TS FILE
import { Component, OnInit } from '@angular/core';
import { Params, ActivatedRoute, Router } from '@angular/router';
import {FormGroup, FormControl, FormArray, Validators} from '@angular/forms';
import { RecipeService } from '../recipe.service';
@Component({
selector: 'app-recipe-edit',
templateUrl: './recipe-edit.component.html',
styleUrls: ['./recipe-edit.component.css']
})
export class RecipeEditComponent implements OnInit {
id:number;
editMode=false;
recipeForm:FormGroup;
constructor(private route:ActivatedRoute,private recipeService:RecipeService,
private router:Router) { }
ngOnInit(): void {
this.route.params.subscribe(
(params:Params)=>{
this.id=+params['id'];
this.editMode=params['id']!=null;
console.log( this.editMode);
this.initForm();//we load it here becoz when our route get change
//then we have to load it(then by it we get to know this page is reload)
}
);
}
get controls(){
return (<formarray>this.recipeForm.get('ingredients')).controls;
}
onSubmit(){
//const newRecipe=new Recipe(
// this.recipeForm.value['name'],
// this.recipeForm.value['description'],
// this.recipeForm.value['imagePath'],
//this.recipeForm.value['ingredients']);
if(this.editMode){
this.recipeService.updateRecipe(this.id,this.recipeForm.value);
}else{
this.recipeService.addRecipe(this.recipeForm.value);
}
this.onCancel();
}
onAddIngredient(){
(<formarray> this.recipeForm.get('ingredients')).push(
new FormGroup({
'name':new FormControl(null,Validators.required),
'amount':new FormControl(null,[Validators.required,Validators.pattern(/^[1-9]+[0-9]+$/)])
})
);
}
onCancel(){
this.router.navigate(['../'],{relativeTo:this.route});
}
onDeleteIngredient(index:number){
(<formarray>this.recipeForm.get('ingredients')).removeAt(index);
}
private initForm() {
let recipeName='';
let recipeImagePath='';
let recipeDescription='';
let recipeIngredients=new FormArray([]);
if(this.editMode){
const recipe=this.recipeService.getRecipe(this.id);
recipeName=recipe.name;
recipeImagePath=recipe.imagePath;
recipeDescription=recipe.description;
if(recipe['ingredients']){
for(let ingredient of recipe.ingredients){
recipeIngredients.push(
new FormGroup({
'name':new FormControl(ingredient.name,Validators.required),
'amount':new FormControl(ingredient.amount,[Validators.required,Validators.pattern(/^[1-9]+[0-9]*$/)])
})
);
}
}
this.recipeForm=new FormGroup(
{
'name':new FormControl(recipeName,Validators.required),
'imagePath':new FormControl(recipeImagePath,Validators.required),
'description':new FormControl(recipeDescription,Validators.required),
'ingredients':recipeIngredients
}
);
}
}
}
the Error Occurring:
core.js:6185 ERROR Error: formGroup expects a FormGroup instance. Please pass one in.
Example:
In your class:
this.myGroup = new FormGroup({
firstName: new FormControl()
});
at Function.missingFormException (forms.js:2342)
at FormGroupDirective._checkFormPresent (forms.js:7724)
at FormGroupDirective.ngOnChanges (forms.js:7514)
at FormGroupDirective.wrapOnChangesHook_inPreviousChangesStorage (core.js:26853)
at callHook (core.js:4690)
at callHooks (core.js:4650)
at executeInitAndCheckHooks (core.js:4591)
at selectIndexInternal (core.js:9621)
at Module.ɵɵadvance (core.js:9582)
at RecipeEditComponent_Template (recipe-edit.component.html:6)
defaultErrorLogger @ core.js:6185
handleError @ core.js:6238
(anonymous) @ core.js:42725
invoke @ zone-evergreen.js:364
run @ zone-evergreen.js:123
runOutsideAngular @ core.js:41122
tick @ core.js:42722
(anonymous) @ core.js:42562
invoke @ zone-evergreen.js:364
onInvoke @ core.js:41286
invoke @ zone-evergreen.js:363
run @ zone-evergreen.js:123
run @ core.js:41061
next @ core.js:42559
schedulerFn @ core.js:36889
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
emit @ core.js:36851
checkStable @ core.js:41200
onHasTask @ core.js:41307
hasTask @ zone-evergreen.js:419
_updateTaskCount @ zone-evergreen.js:440
_updateTaskCount @ zone-evergreen.js:263
runTask @ zone-evergreen.js:184
drainMicroTaskQueue @ zone-evergreen.js:569
invokeTask @ zone-evergreen.js:484
invokeTask @ zone-evergreen.js:1621
globalZoneAwareCallback @ zone-evergreen.js:1647
What I have tried:
tried all solutions from StackOverflow but unable to find the solution