Javascript – Angular material 2 datepicker with [ngmodel]

angulardatepickerformsjavascriptmaterial-design

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

Best Answer

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.