When making an API call to retrieve data and placing that inside of a model, the DatePicker control is throwing an error:
TypeError: date.getTime is not a function
The model has the fields defined as Date type. I can circumvent the problem by re-assigning the data when it is received:
this.event.dateFrom = new Date(event.dateFrom);
However, I am not sure this should be necessary. Is there something else I should be doing, or this something that the DatePicker control should handle for us?
The DatePicker works with Date instances.
Parsing date strings is a non-trivial task and must occur outside the component. Calling new Date() is not reliable method of parsing and may interpret dates differently depending on the browser implementation and user locale.
Check out the Internationalization help topic and use parseDate for consistent results.
I also get this when returning an object from my API that has a property with an ISO date and trying to assign it to the ngModel of the datepicker.
This example is just using a string, but exhibits the same issue;
@clabough, indeed the component will throw an exception in this case. As @tsvetomir, explained the DatePicker expects a Date object as value, documented here.
If you would like work with a JSON result, then you will need to parse it first. There are several benefits of doing so:
Check the modified demo, which uses the suggested approach:
Makes sense, but many people that use the .NET Web API to return a JSON object will run into this since a DateTime property is returned as an ISO string and Angular handles the conversion when displayed (see the demo). This is just going to be different "WTF" moments. :)
Yep, the kendoDate pipe parses the input before the format is done, which is expected. I think that the Angular Date pipe works similarly.
The important caveat here is that the pipe is used only for presentational purposes. It won't modify the model for any reason, where the DatePicker as a form component (one implementing ControlValueAccessor) will modify the bound field. If the type is changed on the fly, then what's the purpose of TypeScript anyway.
I strongly believe that the JSON conversion should be done in a service (kind of middleware) before the form is bound to it. This is applicable to all components that depends on specific type, not only Kendo.
Could the component throw a better message like "Unsupported date format" when it detects a string instead of the confusing "date.getTime is not a function" error?
Definitely! Most probably the error message will point to the documentation where we will show how to handle string -> Date -> string conversion.
The site with the new documentation is uploaded:
http://www.telerik.com/kendo-angular-ui/components/dateinputs/datepicker/#toc-using-with-json
That's an awful suggestion for a fix. We have generic routines that convert JSON into NGRX-Store values. There simply isn't anywhere we can easily convert our strings to dates. On the other hand, it shouldn't be difficult for a component to spot a value is an ISO date and convert it to a date.
Hi @mrpmorris,
Indeed, the component can easily convert an ISO date string to a JavaScript Date instance. What is important here is that the component should work only with Date objects. Our stance was pointed out here - https://github.com/telerik/kendo-angular/issues/652#issuecomment-309682839. The given documentation and suggestions are not fix but rather are our view how to approach the discussed issue.
One-way parsing (string -> Date) is not a feasible solution for a form control. Right now, it always will return a Date instance, which will convert the type of the bound model field from string to Date. Such behavior is wrong and unacceptable. That is why I mentioned that the JSON should be converted to valid form model before the UI is bound to it.
If working with ISO date strings is a must, then you can define a simple setter/getter property that will be able to convert the value from string -> date and back date -> string when needed. Another option will be to define a custom directive that will handle this conversion on component level.
I fully understand that this is not a code-less solution and could be cumbersome when it comes to big projects with a lot of form fields. The best way to proceed from here is to open a UserVoice suggestion. Thus more people could cast their vote for it and will be able to share their requirements there. Based on the users interest we will decide whether to schedule it for further investigation.
@ggkrustev I understand the reasoning behind the component only only working with Date objects, but for improved end-developer satisfaction, it would be nice to have a flag setting like AllowDateTypeConversion. This would acknowledge that they know the type may change from string to date.
Using a getter/setter sounds interesting, do you have an example of implementing that on an object that's returned from an observable?
I'll put together a UserVoice suggestion for the flag setting if someone doesn't beat me to it.
For anyone that's interested in voting for this, I've created a UserVoice request at http://kendoui-feedback.telerik.com/forums/555517-kendo-ui-for-angular-feedback/suggestions/33352846-enable-date-time-components-to-convert-string-type
@clabough check the following plunkr that uses a custom Directive to override the value/valueChange properties:
Please note that this approach won't work with the NgModel or FormControl bindings. If working with them is needed, then the cleanest solution will be to introduce a high order component that will intercept the set and get process of the selected date. Here is a simple plunkr that demonstrates this approach:
@ggkrustev Very nice Georgi! Thanks for the examples.
Most helpful comment
Definitely! Most probably the error message will point to the documentation where we will show how to handle string -> Date -> string conversion.