My timer using AngularJS is not working on HTML page
This is my controller function
setInterval(function () {
var d = new Date();
var seconds = d.getMinutes() * 60 + d.getSeconds();
var fiveMin = 60 * 1;
var timeleft = fiveMin - seconds % fiveMin;
var result = parseInt(timeleft / 60) + ':' + timeleft % 60;
//console.log(result);
var timerObj= {
timer : result
}
$scope.timerArray = timerObj;
if (timeleft === 1) {
$scope.statusDetails = $scope.reset;
$scope.timeDetails();
$scope.get_dbStatus();
$scope.get_sosStatus();
$scope.get_cepStatus();
$scope.get_taskStatus();
$scope.get_mqStatus();
$scope.get_mrStatus();
$scope.get_dmStatus();
}
$scope.$apply();
}, 500);
This is my html page
<table class="table">
<thead>
<tr>
<th class="col-lg-5 col-sm-5">
Name
</th>
<th class="col-lg-2 col-sm-2">
Version
</th>
<th class="col-lg-1 col-sm-3">
Status
</th>
<th class="col-lg-2 col-sm-2">
Contact Info
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="status in statusDetails">
<td>{{status.title}}</td>
<td>{{status.apiVersion}}</td>
<td><img ng-src="../public/tcup/images/{{status.status}}.png"/></td>
<td>-</td>
</tr>
</tbody>
</table>
Timer and everything works fine. But every time the timer gets expired and the list is updated, the updated list is added to the previous list.
source to share
You need to start a new digest cycle because Angular doesn't know you changed something:
setInterval(function () {
var d = new Date();
var seconds = d.getMinutes() * 60 + d.getSeconds();
var fiveMin = 60 * 2;
var timeleft = fiveMin - seconds % fiveMin;
var result = parseInt(timeleft / 60) + ':' + timeleft % 60;
//console.log(result);
var timerObj = {
timer: result
}
$scope.timerArray = timerObj;
console.log("timer...........");
console.log($scope.timerArray.timer);
$scope.$apply(); // <--- apply changes to models
}, 500);
source to share
Instead, setInterval
use $interval
to run the digest loop for you after the function completes.
code
$interval(function () {
var d = new Date();
var seconds = d.getMinutes() * 60 + d.getSeconds();
var fiveMin = 60 * 2;
var timeleft = fiveMin - seconds % fiveMin;
var result = parseInt(timeleft / 60) + ':' + timeleft % 60;
//console.log(result);
var timerObj = {
timer: result
}
$scope.timerArray = timerObj;
console.log("timer...........");
console.log($scope.timerArray.timer);
}, 500)
Edit 1
In order to call the method after the interval is over, you need to call it on the promise chain, you can limit you $interval
to call it a certain amount of time by adding a third parameter that will run the function $interval
during that time.
code
var interval = $interval(function () {
var d = new Date();
var seconds = d.getMinutes() * 60 + d.getSeconds();
var fiveMin = 60 * 2;
var timeleft = fiveMin - seconds % fiveMin;
var result = parseInt(timeleft / 60) + ':' + timeleft % 60;
//console.log(result);
var timerObj = {
timer: result
}
$scope.timerArray = timerObj;
console.log("timer...........");
console.log($scope.timerArray.timer);
}, 500, 10);
interval.then(function(){
//this code will execute after interval completion
//you could call any scope method from here
});
Edit 2
If you call the callback function only once, you shouldn't rely on $interval
, it is better to use $timeout
instead $interval
, it will only run once.
code
var timeout = $timeout(function() {
$scope.statusDetails = [];
$scope.timeDetails();
$scope.get_dbStatus();
$scope.get_sosStatus();
$scope.get_cepStatus();
$scope.get_taskStatus();
$scope.get_mqStatus();
$scope.get_mrStatus();
$scope.get_dmStatus();
}, 120000);
timeout.then(function() {
$scope.repeat()
});
Edit 3
Basically you will need to add one method that is called by a button click with callInterval
which will start $interval
and internally we will maintain a variable intervalPromise
that will check if an interval exists, then it will cancel
so that it is an interval and then create a new interval
code
var intervalPromise;
$scope.callInterval = function() {
if (intervalPromise) //remove interval if already exists
$interval.cancel(intervalPromise);
intervalPromise = $interval(function() {
//..your existing code here
}, 500);
};
source to share