Material: md-datepicker: support string representation of date as a model

Created on 11 Dec 2015  路  24Comments  路  Source: angular/material

The datepicker currently throws error if model given is not a date instance.
With parseDate function available, it would be helpful check if valid dateString is given before throwing an error.

Possible replacement of line 256-259 ref: pull #5503 of src/components/datepicker/datePicker.js:

  if (value && !(value instanceof Date)) {
    var parseValue = self.dateLocale.parseDate(value);
    if (isNaN(parseValue)) {
        throw Error('The ng-model for md-datepicker must be a Date instance. ' +
        'Currently the model is a: ' + (typeof value));
    } else {
        value = parseValue;
    }
  }

Up for discussion

feature

Most helpful comment

This is really annoying, mates :(

When interacting with APIs is highly probably that it returns or expects an ISO 8601 formatted string, so it is just logical that the variable passed to ng-model can be a string too, or at least one must have the possibility to define a parseDate method that converts the string to a valid date before it triggers the error.
Currently the error is thrown before parseDate, enforcing the users to search for hackish alternatives.

All 24 comments

+1
I'm currently getting around this by parsing my responses for dates in order to keep the functionality centralized, but this isn't a very efficient solution. I'd like to see this functionality offloaded to the datepicker.

I copy here my temporal solution, it works fine:

      if (value && !(value instanceof Date)) {
        if (typeof value === "string")
            value = new Date(value);
        if (Object.prototype.toString.call(value) !== "[object Date]")
            throw Error('The ng-model for md-datepicker must be a Date instance. ' +
                'Currently the model is a: ' + (typeof value));
      }

As a general workaround when interacting with JSON data, one could write a custom _Date reviver_ and pass it to JSON#parse() as second parameter (see https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).

From my point of view, this is something that should have been implemented directly into JSON#parse(), but fore sure the devs had their reasons why they did not when initially implementing it. flies away

Yep @super-coder, I think this is the best solution.

Thanks for share.

but the regex is not perfect, i tried another one and here is the updated version http://jsfiddle.net/katfby9L/1/

@super-coder be careful with complex regex.

We have to look for the best option, run a regex or parse date with new Date(value);

Do you know some way to compare two javascript codes/functions and determine what is more efficient?

@tolemac i changed the regex because it wasn't working with past dates from Web API. The new one seems to be working. Would be good to have a confirmed perfect regex...

+1

@super-coder your solution will convert every integer value as a date object, don't?

@marcomafessolli only dates according to regex

This is really annoying, mates :(

When interacting with APIs is highly probably that it returns or expects an ISO 8601 formatted string, so it is just logical that the variable passed to ng-model can be a string too, or at least one must have the possibility to define a parseDate method that converts the string to a valid date before it triggers the error.
Currently the error is thrown before parseDate, enforcing the users to search for hackish alternatives.

Agree with @diosney.

+1

OK, I have solved it by implementing a couple of directives which adds formatters and parsers to the ng-model...

md-datepicker(ng-switch-when="date",ng-model="filter.option",nx-model-formatter="[ 'moment', 'toDate' ]",nx-model-parser="getTime")

What the directives does is to invoke the functions I provide as arguments to the directives on the ng-model for the md-datepicker, and in the sequence they are given if they are an Array.

I already have a dependency on the moment library and want to save the selected date in local storage as a unix epoch, so in the formatters I first create a moment object and then I call toDate on it so the ng-model of the md-datepicker is a native JS date object.
In the parser I simply call getTime on the ng-model which eventually persists the number to the local storage.

This is just a simple hack and only intended for myself to be able to move on, but I thought I would share, maybe someone could find it useful.
If anyone is interested in this solution, I can polish it up and share it in a more friendly format... just let me know.

Formatter: https://gist.github.com/pmoelgaard/5f77b8804e91bfb9440e
Parser: https://gist.github.com/pmoelgaard/fb1294df8a73f553d2c2

@pmoelgaard I'd like to see it. Can you share a codepen too?

@marcomafessolli OK, sure... will post it here when done.

@pmoelgaard based on what you did I did this:
https://gist.github.com/marcomafessolli/4b5289fdab5a9790ec32

Seems to be working good. Thank you

@marcomafessolli I'm happy if I could help you somewhat... I actually just finished a codepen... it was fun to get it to work in that environment, so time was not wasted even you might not need it anymore... :)
http://codepen.io/pmoelgaard/pen/bpbXeM

Now, my code layout is a bit convoluted, it's part of a larger solution... it was never intended to be used outside... but yours looks like it does the job ! :)

@marcomafessolli Tested utcParse directive and worked like a charm, cleanest solution that I've seen so far for this issue.

@marcomafessolli @pmoelgaard Thanks both for coming with this.

@diosney happy to help... it shouldn't be much of a challenge to add error and exception handling and make it general as you can see in my sample, thus having something like ng-model-parse/format directives or to make it specific to the md-datepicker and e.g. have a md-model-parse/format

+1 for ISO 8601 formatted string

Thanks for referencing #7979.

According to this thread and my feedback, how do you feel about moving priority up?

+1

Was this page helpful?
0 / 5 - 0 ratings

Related issues

epelc picture epelc  路  3Comments

ddimitrop picture ddimitrop  路  3Comments

ghost picture ghost  路  3Comments

chriseyhorn picture chriseyhorn  路  3Comments

achaussende picture achaussende  路  3Comments