Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular-UI date picker is in invalid state when specified the date format as 'd-M-yyyy' and ng-model with a string value as "2014-08-31T00:00:00Z"

I am getting a date time value from asp.net mvc controller as "2014-08-31T00:00:00Z". When I bind this value to my angular-ui datepicker control it's state is showing as ng-invalid ng-invalid-date.

I am getting the date-format as well from the mvc controller so I am binding the date-format as well in my html.

When I am debugging the ui-bootstrap-tpls.js (latest version) file at line 1807

enter image description here

It's always coming as undefined. I have tried so many alternatives but I am unable to succeed. :(

javascript does't convert angular ui datepicker date to UTC correctly

So please give some thoughts and suggest me how can I solve this problem.

Thanks & Regards, N.Murali Krishna.

like image 251
Murali Krishna Avatar asked Oct 08 '15 13:10

Murali Krishna


2 Answers

I had the same problem. The issue is that Angular is expecting an actual date object, not a string representation of the date. After doing a bunch of research I ended up adding a transformReponse to the $httpProvider which checks all string objects to see if they can be converted to a date, and if so actually converting them.

angular.module('test')
.config(['$httpProvider', function ($httpProvider) {

    // ISO 8601 Date Pattern: YYYY-mm-ddThh:MM:ss
    var dateMatchPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/;

   var convertDates = function (obj) {
      for (var key in obj) {
         if (!obj.hasOwnProperty(key)) continue;

         var value = obj[key];
         var typeofValue = typeof (value);

         if (typeofValue === 'object') {
            // If it is an object, check within the object for dates.
            convertDates(value);
         } else if (typeofValue === 'string') {
            if (dateMatchPattern.test(value)) {
               obj[key] = new Date(value);
            }
         }
      }
   }

   $httpProvider.defaults.transformResponse.push(function (data) {
      if (typeof (data) === 'object') {
         convertDates(data);
      }

      return data;
   });
}])
like image 100
Chet Avatar answered Oct 20 '22 01:10

Chet


A couple of notes here:

  1. First, the datepicker directive requires that the ng-model be a Date object. This is documented here.
  2. Second, the solution posted (and accepted) by Chet above is VERY heavy-handed as it takes EVERY date string received in an HTTP response and converts it to a Date object if it matches a hard-coded pattern. This is not flexible nor is it easily testable. It will not be the right solution for most people.

If, in your system, global date string conversion is the right behavior, the proper Angular design would be to create a service that does this for you. This leads me to...

We've (Angular UI Bootstrap) provided a mechanism for converting date strings into Date objects via the dateParser service. You can see the source code here. NB: this service name becomes deprecated and changed to uibDateParser with the 0.14.0 release.

like image 23
icfantv Avatar answered Oct 19 '22 23:10

icfantv