My code environment is Angular 9, and when I set up reactive form, I met this error:
error NG8002: Can't bind to 'formGroup' since it isn't a known property of 'form'.
I did some researches in Google and StackOverflow, but can't find the same questions with using Angular 9, however, based on other posts suggestions, I do import ReactiveFormsModule into app.module.ts, routing.module.ts and also recipe-edit.component.spec.ts files. However, the error keeps popping up. I attach my code, and somebody could give me suggestions?
app.module.ts
import { RecipeService } from './recipes/recipe.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule} from '@angular/forms';
import { RoutingModule } from './routing.module';
import { ShoppingListService } from './shopping-list/shopping-list.service';
import { AppComponent } from './app.component';
import { RecipesComponent } from './recipes/recipes.component';
import { RecipeListComponent } from './recipes/recipe-list/recipe-list.component';
import { RecipeItemComponent } from './recipes/recipe-list/recipe-item/recipe-item.component';
import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component';
import { HeaderComponent } from './header/header.component';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { ShoppingEditComponent } from './shopping-list/shopping-edit/shopping-edit.component';
import { DropdownDirective } from './shared/dropdown.directive';
@NgModule({
declarations: [
AppComponent,
RecipesComponent,
RecipeListComponent,
RecipeItemComponent,
RecipeDetailComponent,
HeaderComponent,
ShoppingListComponent,
ShoppingEditComponent,
DropdownDirective
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
RoutingModule
],
providers: [ShoppingListService, RecipeService],
bootstrap: [AppComponent]
})
export class AppModule { }
routing.module.ts
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { RecipeStartComponent } from './recipes/recipe-start/recipe-start.component';
import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { RecipesComponent } from './recipes/recipes.component';
import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component';
const routes: Routes = [
{path: '', redirectTo: '/recipes', pathMatch: 'full'},
{path: 'recipes', component: RecipesComponent, children: [
{path: '', component: RecipeStartComponent},
{path: 'new', component: RecipeEditComponent},
{path: ':id', component: RecipeDetailComponent},
{path: ':id/edit', component: RecipeEditComponent}
]},
{path: 'shopping-list', component: ShoppingListComponent}
];
@NgModule({
imports: [RouterModule.forRoot(routes), FormsModule, ReactiveFormsModule],
exports: [RouterModule]
})
export class RoutingModule {}
recipe-edit.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { FormGroup, FormControl } 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) { }
ngOnInit() {
this.route.params
.subscribe(
(paras: Params) => {
this.id = +paras.id;
this.editMode = paras.id != null;
this.initForm();
}
);
}
private initForm() {
let name = '';
let imagePath = '';
let description = '';
if (this.editMode) {
const editRecipe = this.recipeService.getRecipe(this.id);
name = editRecipe.name;
imagePath = editRecipe.imagePath;
description = editRecipe.desc;
}
this.recipeForm = new FormGroup({
name: new FormControl(name),
imagePath: new FormControl(imagePath),
description: new FormControl(description)
});
}
onSubmit() {
console.log(this.recipeForm);
}
}
recipe-edit.component.html
<div class="row">
<div class="col-xs-12">
<form (ngSubmit) = "onSubmit()" [formGroup] = "recipeForm" >
<div class="row">
<div class="col-xs-12">
<button class="btn btn-success" type = "submit"> Save </button>
<button class="btn btn-danger" type = "button"> Cancel </button>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label for="name"> Recipe 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"> Image URL </label>
<input
type = "text"
id = "imagePath"
formControlName="imagePath"
class="form-control">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<img src="" class="img-reponsive">
</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">
<div class="row">
<div class="col-xs-8">
<input
type = "text"
class = "form-control">
</div>
<div class="col-xs-2">
<input
type = "number"
class = "form-control">
</div>
<div class="col-xs-2">
<button class="btn btn-danger" type = "button"> X </button>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
recipe-edit.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RecipeEditComponent } from './recipe-edit.component';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
describe('RecipeEditComponent', () => {
let component: RecipeEditComponent;
let fixture: ComponentFixture<RecipeEditComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ RecipeEditComponent ],
imports: [ReactiveFormsModule, FormsModule]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(RecipeEditComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
If the RecipeEditComponent
belongs to AppModule, you need to declare the RecipeEditComponent
in app.module.ts
:
import { RecipeService } from './recipes/recipe.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule} from '@angular/forms';
import { RoutingModule } from './routing.module';
import { ShoppingListService } from './shopping-list/shopping-list.service';
import { AppComponent } from './app.component';
// Add following line:
import { RecipeEditComponent } from './recipes/recipe-edit/recipe-edit.component'; // add this
import { RecipesComponent } from './recipes/recipes.component';
import { RecipeListComponent } from './recipes/recipe-list/recipe-list.component';
import { RecipeItemComponent } from './recipes/recipe-list/recipe-item/recipe-item.component';
import { RecipeDetailComponent } from './recipes/recipe-detail/recipe-detail.component';
import { HeaderComponent } from './header/header.component';
import { ShoppingListComponent } from './shopping-list/shopping-list.component';
import { ShoppingEditComponent } from './shopping-list/shopping-edit/shopping-edit.component';
import { DropdownDirective } from './shared/dropdown.directive';
@NgModule({
declarations: [
AppComponent,
RecipesComponent,
RecipeEditComponent, // add this and the import line
RecipeListComponent,
RecipeItemComponent,
RecipeDetailComponent,
HeaderComponent,
ShoppingListComponent,
ShoppingEditComponent,
DropdownDirective
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule,
RoutingModule
],
providers: [ShoppingListService, RecipeService],
bootstrap: [AppComponent]
})
export class AppModule { }
Otherwise if it belongs to another module, you need to import FormsModule
and ReactiveFormsModule
in the module which it belongs to.
you need to import FormsModule
and ReactiveFormsModule
in the module which it belongs to.
import {ReactiveFormsModule, FormsModule } from '@angular/forms';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With