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.

+3


source to share


2 answers


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);

      

+2


source


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);
};

      

0


source







All Articles