Error on crash: [$ rootScope: infdig] while implementing elapsed time calculator
I am getting this error in the browser console in my code for the elapsed time calculator:
Uncaught Error: [$rootScope:infdig]
I am calculating the elapsed time from the current time when the application starts.
Here is my html:
<div ng-app="time">
<div ng-controller="Ctrl2">
Elapsed time: <span my-current-time="[date,format]"></span>
</div>
</div>
Here is the JavaScript code:
function Ctrl2($scope) {
$scope.date = new Date();
$scope.format = 'M/d/yy h:mm:ss a';
}
angular.module('time', [])
// Register the 'myCurrentTime' directive factory method.
// We inject $timeout and dateFilter service since the factory method is DI.
.directive('myCurrentTime', function($timeout, dateFilter) {
// return the directive link function. (compile function not needed)
return function(scope, element, attrs) {
var format, // date format
timeoutId; // timeoutId, so that we can cancel the time updates
var since;
// used to update the UI
function updateTime() {
element.text(dateFilter(since, format));
element.text( (((new Date()).getTime() - since.getTime())/(1000*60)%60) + " minutes, since " + dateFilter(since, format));
}
// watch the expression, and update the UI on change.
//scope.$watch(attrs.myCurrentTime, function(value) {
// format = value;
// updateTime();
//});
scope.$watch(attrs.myCurrentTime, function(value) {
since = value[0];
format = value[1];
updateTime();
});
// schedule update in one second
function updateLater() {
// save the timeoutId for canceling
timeoutId = $timeout(function() {
updateTime(); // update DOM
updateLater(); // schedule another update
}, 1000);
}
// listen on DOM destroy (removal) event, and cancel the next UI update
// to prevent updating time ofter the DOM element was removed.
element.bind('$destroy', function() {
$timeout.cancel(timeoutId);
});
updateLater(); // kick off the UI update process.
}
});
Please help, I also made a fiddle to see the code
source to share
Looks like I found the problem. I have an assumption that angular creates new arrays for each evaluation, so the watcher always starts
function Ctrl2($scope) {
$scope.date = new Date();
$scope.format = 'M/d/yy h:mm:ss a';
$scope.options = [$scope.date, $scope.format]; //<--line added
}
<div ng-app="time">
<div ng-controller="Ctrl2">
Elapsed time: <span my-current-time="options"></span> //<-- binding change.
</div>
</div>
ADDED
Also not sure if you really need these watch functions. Keep in mind that the clock runs on the whole array in your case, not on the inner elements. You can extract the value scope.$eval(attrs.myCurrentTime)
.
source to share