9

The error occurs when I display the populated, editable form to the user (not when a user enters in data and submits). The data is coming from MySQL over REST/JSON in the service shown below:

HTML:

<input class="form-control" type="date" name="dateInput" id="dateOfBirth" 
                   ng-model="user.dateOfBirth">

CCONTROLLER:

.controller('EditCtrl', function ($scope, $routeParams, UserDetail, $window) {
        $scope.user = UserDetail.find({}, {'id': $routeParams.id});
}

SERVICE:

service.factory('UserDetail', function ($resource) {

    return $resource(
        'http://localhost:8080/ClearsoftDemoBackend/webresources/clearsoft.demo.users/:id',
        {id: '@id'},
    {
    find: {method: 'GET'},

    });
});

ERROR:

Error: [ngModel:datefmt] Expected 2010-05-13T00:00:00-04:00 to be a date

2
  • the input value is a string, not a date. you can call new Date(input.value) to get a real date object. Commented Nov 10, 2014 at 21:23
  • 1
    In the controller? Tried that and it seems to get overwritten ... Perhaps when a promise returns from service? Commented Nov 11, 2014 at 0:11

5 Answers 5

13

AngularJS 1.3 adds to input [date | datetime-local ] fields a new formatter/parser that checks that the model is a Date Object and throw the datefmt exception.

if (value && !isDate(value)) {
    throw $ngModelMinErr('datefmt', 'Expected `{0}` to be a date', value);

This issue is not present at previos versions and I suggest get in consideration on upgrade to avoid big nightmares.

A workaroud is to reset default formatters/parser with a custom dateFormat directive and use momentjs to format,parse strings to Date.

define(['directives/directives','momentjs'], function(directives,momentjs) {
directives.directive('dateFormat', function() {
      return {
        require: 'ngModel',
        link: function(scope, element, attr, ngModelCtrl) {
          var format=attr.dateFormat;
          //Angular 1.3 insert a formater that force to set model to date object, otherwise throw exception.
          //Reset default angular formatters/parsers
          ngModelCtrl.$formatters.length=0;
          ngModelCtrl.$parsers.length=0;

          ngModelCtrl.$formatters.push(function(valueFromModel) {
             //return how data will be shown in input
              if(valueFromModel){
                 // For momentjs > 2.9 moment global va is not defined use momentjs instead of moment.
                  return moment(valueFromModel).format(format);
              }
              else
                  return null;
          });
          ngModelCtrl.$parsers.push(function(valueFromInput) {
              if(valueFromInput){
                  //For momentjs > 2.9 moment global va is not defined use momentjs instead of moment.
                  return moment(valueFromInput,format).toDate();
              }
              else 
                  return null;
          });
        }
      };
    });
});

UPDATE With momentjs > 2.9 take in consideration that the moment global var are not defined.

2.9 "Deprecation warning: Accessing Moment through the global scope is deprecated, and will be removed in an upcoming release."

With AMD need use momentjs instead of moment. i.e:

return momentjs(valueFromModel).format(format);
Sign up to request clarification or add additional context in comments.

1 Comment

After wasting whole day, finally, this solution works!! For input type datetime-local, I used date-format="YYYY-MM-DDTHH:mm" and got it working on Ionic app. Thanks for sharing.
6

Its because that is not a valid date according to Angular. Check out the doc on input[date] for their note on date validation. For it to be a date it should be in the format of YYYY-MM-DD.

3 Comments

@vt97john This sounds like a separate question. You should write up a new one and include more of your code so that we can see what is going on with it.
I added more code to the above. Where / how can I properly format the date?
I finally got it working. My original attempt to format failed because it was overwritten after a promise returned from a service call. I had to do the formatting using a "transformResponse" on the service ($resource) response to get it to work. find: { method: 'GET', transformResponse: function (data) { data = angular.fromJson(data); data.dateOfBirth = new Date(data.dateOfBirth); return data; } }
1

In your api

$date = date("Y-m-d");
$new_date = date("c",strtotime($date));
echo json_encode(array("date"=>$new_date));

In your controller

/* var date 
* this is value from your api
*/
$scope.date = new Date(date);

Comments

1

For date value in an array one can use this as:

    var dates = [
      { id: "1" , date: "2015-04-20T11:24:20.882Z"},
      { id: "2" , date: "2015-05-20T11:24:20.882Z"},
      { id: "3" , date: "2015-06-20T11:24:20.882Z"},
    ];

      function dateStringToObject (data) {
        for(var i=0; i < data.length; i++ ){
          data[i].date = new Date(data[i].date);
          }

        return data;
      }

   dateStringToObject(dates);

Comments

0

Basically its not about the format, it want a valid new Date() object in ISO format ,so whatever you get response ,just do a new Date and angular will be happy , i got this when i parsed the exception message caused by angular

https://docs.angularjs.org/error/ngModel/datefmt?p0=2015-11-24

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.