Though the answer solves the issue, I would like to provide a little more information on this topic as I have also undergone this issue when I started to work on Angular projects.
A beginner should understand that there are two main types of forms. They are Reactive forms and Template-driven forms. From Angular 2 onward, it is recommended to use Reactive forms for any kind of forms.
Reactive forms are more robust: they're more scalable, reusable, and testable. If forms are a key part of your application, or you're already using reactive patterns for building your application, use reactive forms.
Template-driven forms are useful for adding a simple form to an application, such as an email list signup form. They're easy to add to an application, but they don't scale as well as reactive forms. If you have very basic form requirements and logic that can be managed solely in the template, use template-driven forms.
Refer Angular documents for more details.
Coming to the question, [(ngModel)]="..."
is basically a binding syntax. In order to use this in your component HTML page, you should import FormsModule in your NgModule (where your component is present). Now [(ngModel)]
is used for a simple two-way binding or this is used in your form for any input HTML element.
On the other hand, to use reactive forms, import ReactiveFormsModule
from the @angular/forms
package and add it to your NgModule's imports array.
For example, if my component HTML content does not have [(ngmodel)] in any HTML element, then I don't need to import FormsModule.
In my below example, I have completely used Reactive Forms and hence I don't need to use FormsModule in my NgModule.
Create GroupsModule:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GroupsRoutingModule, routedAccountComponents } from './groups-routing.module';
import { ReactiveFormsModule } from '@angular/forms';
import { SharedModule } from '../shared/shared.module';
import { ModalModule } from 'ngx-bootstrap';
@NgModule({
declarations: [
routedAccountComponents
],
imports: [
CommonModule,
ReactiveFormsModule,
GroupsRoutingModule,
SharedModule,
ModalModule.forRoot()
]
})
export class GroupsModule {
}
Create the routing module (separated to main the code and for readability):
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { GroupsComponent } from './all/index.component';
import { CreateGroupComponent } from './create/index.component';
const routes: Routes = [
{
path: '',
redirectTo: 'groups',
pathMatch: 'full'
},
{
path: 'groups',
component: GroupsComponent
}
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class GroupsRoutingModule { }
export const routedAccountComponents = [
GroupsComponent,
CreateGroupComponent
];
CreateGroupComponent html code
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<label for="name">Group Name</label>
<div class="form-group">
<div class="form-line">
<input type="text" formControlName="name" class="form-control">
</div>
</div>
</form>
CreateGroupComponent ts file
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { DialogResult } from 'src/app/shared/modal';
import { FormGroup, FormControl, AbstractControl } from '@angular/forms';
import { Subject } from 'rxjs';
import { ToastrService } from 'ngx-toastr';
import { validateAllFormFields } from 'src/app/services/validateAllFormFields';
import { HttpErrorResponse } from '@angular/common/http';
import { modelStateFormMapper } from 'src/app/services/shared/modelStateFormMapper';
import { GroupsService } from '../groups.service';
import { CreateGroup } from '../model/create-group.model';
@Component({
selector: 'app-create-group',
templateUrl: './index.component.html',
providers: [LoadingService]
})
export class CreateGroupComponent implements OnInit {
public form: FormGroup;
public errors: string[] = [];
private destroy: Subject<void> = new Subject<void>();
constructor(
private groupService: GroupsService,
private toastr: ToastrService
) { }
private buildForm(): FormGroup {
return new FormGroup({
name: new FormControl('', [Validators.maxLength(254)])
});
}
private getModel(): CreateGroup {
const formValue = this.form.value;
return <CreateGroup>{
name: formValue.name
};
}
public control(name: string): AbstractControl {
return this.form.get(name);
}
public ngOnInit() {
this.form = this.buildForm();
}
public onSubmit(): void {
if (this.form.valid) {
// this.onSubmit();
//do what you need to do
}
}
}
I hope this helps developers to understand as to why and when you need to use FormsModule.
ngModel
into appModule. Say you havesecondModule
, andthirdModule
and you import onlysecondModule
intoappModule
and you importthirdModule
intosecondModule
and thenthirdModule
trys to usengModel
, you'll get this error until you importthirdModule
intoappModule
. – Ima