Skip to content

Commit 91c0a69

Browse files
committed
fix(datepicker): throw when value is set to invalid type
BREAKING CHANGE: You must now use an actual Date object rather than a string when setting the value of the datepicker programmatically (through value, ngModel, or formControl).
1 parent ac104c3 commit 91c0a69

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

src/lib/core/datetime/date-adapter.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ export abstract class DateAdapter<D> {
156156
*/
157157
abstract getISODateString(date: D): string;
158158

159+
/**
160+
* Checks whether the given value is a date object of type `D`.
161+
* @param value The value to check.
162+
* @returns Whether the value is a date object of type `D`.
163+
*/
164+
abstract isDateObject(value: any): boolean;
165+
159166
/**
160167
* Sets the locale used for all dates.
161168
* @param locale The new locale.

src/lib/core/datetime/native-date-adapter.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,10 @@ export class NativeDateAdapter extends DateAdapter<Date> {
192192
].join('-');
193193
}
194194

195+
isDateObject(value: any) {
196+
return value instanceof Date;
197+
}
198+
195199
/** Creates a date but allows the month and date to overflow. */
196200
private _createDateWithOverflow(year: number, month: number, date: number) {
197201
let result = new Date(year, month, date);

src/lib/datepicker/datepicker-input.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,14 @@ export class MdDatepickerInput<D> implements AfterContentInit, ControlValueAcces
9999
this._dateFormats.parse.dateInput);
100100
}
101101
set value(value: D | null) {
102-
let date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput);
102+
if (value != null && !this._dateAdapter.isDateObject(value)) {
103+
throw new Error('Datepicker: value not recognized as a date object by DateAdapter.');
104+
}
103105
let oldDate = this.value;
104106
this._renderer.setProperty(this._elementRef.nativeElement, 'value',
105-
date ? this._dateAdapter.format(date, this._dateFormats.display.dateInput) : '');
106-
if (!this._dateAdapter.sameDate(oldDate, date)) {
107-
this._valueChange.emit(date);
107+
value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '');
108+
if (!this._dateAdapter.sameDate(oldDate, value)) {
109+
this._valueChange.emit(value);
108110
}
109111
}
110112

src/lib/datepicker/datepicker.spec.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,14 @@ describe('MdDatepicker', () => {
189189
expect(attachToRef.nativeElement.tagName.toLowerCase())
190190
.toBe('input', 'popup should be attached to native input');
191191
});
192+
193+
it('should throw when given wrong data type', () => {
194+
testComponent.date = '1/1/2017' as any;
195+
196+
expect(() => fixture.detectChanges()).toThrow();
197+
198+
testComponent.date = null;
199+
});
192200
});
193201

194202
describe('datepicker with too many inputs', () => {
@@ -767,7 +775,7 @@ describe('MdDatepicker', () => {
767775
class StandardDatepicker {
768776
touch = false;
769777
disabled = false;
770-
date = new Date(2020, JAN, 1);
778+
date: Date | null = new Date(2020, JAN, 1);
771779
@ViewChild('d') datepicker: MdDatepicker<Date>;
772780
@ViewChild(MdDatepickerInput) datepickerInput: MdDatepickerInput<Date>;
773781
}

0 commit comments

Comments
 (0)