Warpasaur
Warpasaur

Reputation: 170

Date object in Angular

Can someone explain why the input with ng-model in this plunk is not updated when the button is pressed?

http://plnkr.co/edit/8JpyUVM8dY8aoV4fi5hC?p=preview

HTML

  <body ng-controller="MainCtrl">
    Using ng-model:  <input type="text" ng-model="myDate"><br/>
    Using expression: {{ myDate  }}<br/>
    <button ng-click="nextDay()">Next Day</button>
  </body> 

JS

app.controller('MainCtrl', function($scope) {
  $scope.myDate = new Date();
  $scope.nextDay = function(){
    $scope.myDate.setDate($scope.myDate.getDate() + 1);
  };
});

Upvotes: 6

Views: 9096

Answers (5)

Carlos Perea
Carlos Perea

Reputation: 616

Working Plunker: http://plnkr.co/edit/ku8iy0YKvQfBdolg7cug?p=preview

Change your controller to:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.myDate = new Date();
  $scope.nextDay = function(){
     var newDate = new Date($scope.myDate.setDate($scope.myDate.getDate() + 1));
     $scope.myDate = newDate;
  };
});

Like others mentioned, the reference to the instance hasn't changed so Angular doesn't know it needs to render it again. By changing the Date object entirely you are forcing Angular to render the changed model.

Upvotes: 4

sirrocco
sirrocco

Reputation: 8055

So what happens is that angularjs maintains a reference watch of the date object you set initially. Using the setDate method doesn't change the reference so angular doesn't know it changed.

That's why:

var newDate = new Date();
newDate.setDate($scope.myDate.getDate() + 1);
$scope.myDate = newDate;

Works.

Upvotes: 0

Kosta
Kosta

Reputation: 463

real answer you can find here. You can't use ng-model with <input/>. Off course you can find a lot of alternatives like binding with {{}}.

@Marc Actually ng-bind binds the text content of the element, not its value. Because of this, it can't be used in elements

Upvotes: -2

Riad Baghbanli
Riad Baghbanli

Reputation: 3319

Since input takes a string, toString() is implicly called on myDate. Do this instead:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.myDate = new Date();
  $scope.myDateStr = $scope.myDate.toString();
  $scope.nextDay = function(){
    $scope.myDate.setDate($scope.myDate.getDate() + 1);
    $scope.myDateStr = $scope.myDate.toString();
  };
});

In your HTML:

<input type="text" ng-model="myDateStr"> 

Upvotes: 0

domitall
domitall

Reputation: 655

Instead of updating the date with the setDate method, set a new value to the $scope.myDate object with a locally created version of your updated date.

$scope.myDate.setDate($scope.myDate.getDate() + 1);

becomes

var newDate = new Date();
newDate.setDate($scope.myDate.getDate() + 1);
$scope.myDate = newDate;

Upvotes: 0

Related Questions