18

I am trying to bind my date property to mat-datepicker's input as part of a reactive form group. All of my methods didn't work, as my submit button is set to disabled unless the form is valid:

<mat-form-field fxFlex>
  <input matInput [matDatepicker]="datepicker1" placeholder="Start Date" formControlName="startingDate" required>
  <mat-datepicker-toggle matSuffix [for]="datepicker1"></mat-datepicker-toggle>
  <mat-datepicker touchUi="true" #datepicker1></mat-datepicker>
</mat-form-field>

Component.ts:

start: Date.now()
startDate: "1/1/2018"
this.ShiftForm = new FormGroup({
  startingDate: new FormControl(this.startDate),
  startTime: new FormControl(),
  endingDate: new FormControl(this.endDate),
  endTime: new FormControl(),
});

Methods which didn't work:

  1. Adding [(ngModel)]="startDate" to input field
  2. Adding [ngModel]="startDate" to input field
  3. Preloading the formControl with the value: startingDate: new FormControl(this.startDate),

Methods which partially but not satisfyingly worked:

  1. Adding [value]="startDate" to input field: date showed but not read by the Reactive Form, meaning my submit button remains disabled as the form is not valid. To make it valid, I have to set the date manually (typing or using the datepicker)
  2. Adding [ngModel]="startDate" while removing [matDatepicker]="datepicker1" from the input field: date showed but removing the access to the datepicker.

All I need is the [ngModel] to work as it should so the Reactive Form reads it.

Help much much appreciated!

EDIT This is my formGroup:

this.ShiftForm = new FormGroup({
  startingDate: new FormControl(this.startDate),
  startTime: new FormControl(),
  endingDate: new FormControl(this.endDate),
  endTime: new FormControl(),
});

This is the HTML:

<form [formGroup]="ShiftForm" fxLayout="column" fxLayoutAlign="center stretch">
<mat-form-field fxFlex>
  <input matInput [matDatepicker]="datepicker1" placeholder="Start Date" [formControlName]="startingDate" required>
  <mat-datepicker-toggle matSuffix [for]="datepicker1"></mat-datepicker-toggle>
  <mat-datepicker touchUi="true" #datepicker1></mat-datepicker>
</mat-form-field>
..
..
..
</form>

This is the Error I get now:

Error: Cannot find control with unspecified name attribute

1 Answer 1

39

Angular provides two ways of using forms: template-driven or reactive. You're mixing those two up, while you should choose which one you want to use. The docs can guide you in this choice.

Should you choose template-driven, you can use [(ngModel)] (like your method 1).

<input matInput [matDatepicker]="datepicker1" placeholder="Start Date" [(ngModel)]="startDate" required>

startDate = new Date();

Choose reactive and you can use [formControl] with a FormControl in your controller (like your method 3).

<input matInput [matDatepicker]="datepicker1" placeholder="Start Date" [formControl]="startDate">

startDate = new FormControl(new Date(), Validators.Required);
// Use `startDate.value` to get the value of the control

Never use [value] if you don't know what you're doing or it will give you unexpected results.

Sign up to request clarification or add additional context in comments.

7 Comments

I tried <input matInput [matDatepicker]="datepicker1" placeholder="Start Date" [formControlName]="startDate"> But got an error: Cannot find control with name: '1/2/2018'
You’re using formControlName while you should use formControl, unless you’re using a FormGroup. Then assign a FormControl to startDate in your controller like I posted. Check the guide on reactive forms I linked to, it has lots of examples.
The wierd part is that it iis a part of a FormGroup.. I edited the code above
Remove the []s from your formControlName binding. It’s now trying to bind to the controller property startingDate, which does not exist. You need to bind it to a string of the FormControls name: either formControlName="startingDate" or [formControlName]="'startingDate'".
Which gets me back to step 1: with this setup, for some reason, the value doesn't show
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.