Reputation: 2963
I am attempting to work with Angular Material (8) Reactive Forms
. I am working on a Registration Form. I am getting errors that seem to contradict each other.
**
**
<!-- Form -->
<form [formGroup]="registerForm" class="text-center" style="color: #757575;">
<div class="form-col">
<div class="col">
<!-- First name -->
<div class="md-form">
<input required type="text" id="materialRegisterFormFirstName" class="form-control"
mdbInput [(ngModel)]="user.firstname"/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
</div>
[... snip ...]
**
**
ERROR Error:
ngModel cannot be used to register form controls with a parent formGroup directive. Try using
formGroup's partner directive "formControlName" instead.
So, I follow the instructions. When I use this approach (adding in formControlName="firstname
"),
<div class="form-col">
<div class="col">
<!-- First name -->
<div class="md-form">
<input required type="text" id="materialRegisterFormFirstName" class="form-control"
mdbInput formControlName="firstname" [(ngModel)]="user.firstname"/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
</div>
[... snip ...]
**
**
forms.js:2312
It looks like you're using ngModel on the same form field as formControlName.
Support for using the ngModel input property and ngModelChange event with
reactive form directives has been deprecated in Angular v6 and will be removed
in Angular v7.
For more information on this, see our API docs here:
https://angular.io/api/forms/FormControlName#use-with-ngmodel
When looking up the problem, I come across this in an old thread:
From Angular 7 and onward you can't use both formControlName and ngModel together. If you want to use template-driven forms you can go with ngModel and if you want to use reactive forms you can't go with ngModel. (Simple)
**
formControlName
reference. How can this problem be resolved?**
TIA
Upvotes: 0
Views: 1912
Reputation: 344
You Cannot use both ngModel and FormControlName
or ngModel and formGroup
together. Because ngModel
is a template forms driven whereas FormControlName
and FormGroup
are reactive forms driven.
If you want to use both together you are increasing the complexity of the application. If you want to access the value through formControlName then use it like
<form [formGroup]="registerForm" class="text-center" style="color: #757575;">
<div class="form-col">
<div class="col">
<div class="md-form">
<input formControlName="firstName" type="text" id="materialRegisterFormFirstName" class="form-control" mdbInput/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
</div>
</div>
</form>
In component.ts file write like
registerForm = new FormGroup({
firstName: new FormControl([Validator.required]),
});
or else you can build formgroup using formbuilder, fb
is an instance of formBuilder
this.registerForm = fb.group({
'fullname': ['', Validators.required],
});
and you can read value like this
this.user.firstName = this.registerForm.get('firstName').value;
Upvotes: 2
Reputation: 872
That is because you are using template-driven and reactive form at the same time. You need to use it one of them, you cant use both at same time.
Syntax of template driven form is as below.
.html
file
<div class="row">
<div class="col-xs-12">
<form (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-sm-5 form-group">
<label for="courseName">Course Name</label>
<input
type="text"
id="courseName"
class="form-control"
name="courseName"
ngModel>
</div>
<div class="col-sm-2 form-group">
<label for="courseDesc">Course Description</label>
<input
type="text"
id="courseDesc"
class="form-control"
name="courseDesc"
ngModel>
</div>
<div class="col-sm-2 form-group">
<label for="courseAmount">Course Amount</label>
<input
type="number"
id="courseAmount"
class="form-control"
name="courseAmount"
ngModel>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button
class="btn btn-success"
type="submit">Add</button>
<button
class="btn btn-danger"
type="button">Delete</button>
<button class="btn btn-primary" type="button">Clear</button>
</div>
</div>
</form>
</div>
</div>
.ts
file
onSubmit(form: NgForm) {
console.log("Course Name is : " + form.value.courseName);
console.log("Course Desc is : " + form.value.courseDesc);
console.log("Course Amount is : " + form.value.courseAmount);
}
Syntax for Reactive Form as below
.html
file.
<div class="row">
<div class="col-xs-12">
<form [formGroup]="courseForm" (ngSubmit)="onSubmit()">
<div class="row">
<div class="col-sm-5 form-group">
<label for="courseName">Course Name</label>
<input
type="text"
id="courseName"
class="form-control"
formControlName="courseName">
</div>
<div class="col-sm-2 form-group">
<label for="courseDesc">Course Description</label>
<input
type="text"
id="courseDesc"
class="form-control"
formControlName="courseDesc">
</div>
<div class="col-sm-2 form-group">
<label for="courseAmount">Course Amount</label>
<input
type="number"
id="courseAmount"
class="form-control"
formControlName="courseAmount">
</div>
</div>
<div class="row">
<div class="col-xs-12">
<button
class="btn btn-success"
type="submit">Add</button>
<button
class="btn btn-danger"
type="button">Delete</button>
<button class="btn btn-primary" type="button">Clear</button>
</div>
</div>
</form>
</div>
</div>
.ts
file
this.courseForm = new FormGroup({
'courseName': new FormControl(null, Validators.required),
'courseDesc': new FormControl([Validators.required, Validators.minLength(100)]),
'courseAmount': new FormControl(null)
});
for more reference visit
Upvotes: 3
Reputation: 1573
since you are using reactive forms , no need to use ngModel
in your input fields use formControlName
insted. ngModel
is used in template driven froms
<div class="md-form">
<input required type="text" id="materialRegisterFormFirstName" class="form-control"
mdbInput formControlName="firstname"/>
<label for="materialRegisterFormFirstName">First name</label>
</div>
here you can find better examples https://v8.angular.io/guide/reactive-forms
Upvotes: 0
Reputation: 41387
Use [ngModelOptions]="{ standalone: true }"
on the input element
Upvotes: 0