Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 9 - Can't bind to 'formGroup' since it isn't a known property of 'form' [duplicate]

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();
  });
});
like image 449
John Avatar asked Sep 11 '25 22:09

John


2 Answers

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.

like image 126
Elias Soares Avatar answered Sep 14 '25 12:09

Elias Soares


you need to import FormsModule and ReactiveFormsModule in the module which it belongs to.

import {ReactiveFormsModule, FormsModule } from '@angular/forms';

like image 40
trabelssi bassem Avatar answered Sep 14 '25 10:09

trabelssi bassem