AngularJS $interval displays timer (when the interval will elapse) - javascript

Hi am new to Angular am using $interval to call a function periodically and i want to display a timer in the screen when the next function call will happen , a countdown to the next call . is there anyway simple way to do within this function .
function init(){
$scope.interval = $interval(function(){
$scope.loading = true;
//$scope.countdown = countdown to next call;
doSomework();
}, 60000);
}
Any suggestions are welcome .Thanks in advance

function init(){
var remainingTime = 60;
var interval = $interval(function(){
$scope.loading = true;
remainingTime = remainingTime - 1;
$scope.showRemainingTIme = remainingTime; // Use this variable to show on the view page
if(remainingTime == 0) {
$interval.cancel(interval);
doSomework();
}
}, 1000);
}

Here is what you need. The second argument in $interval is the time after which you want the function to execute and its in miliseconds so 1000ms=1sec.
So after every second it will reduce thhe value of $scope.remainingTimeby 1. You can have the value according to your requirement. Just for demo i have considered it to be 60 and the interval to be 1sec so after every second the $scope.remainingTimewill be decremented by 1
angular.module('timerApp', []);
angular.module('timerApp').controller('timerController', ['$scope', '$interval', function ($scope, $interval) {
$scope.remainingTime = 60;
$scope.timeInterval=$interval(function(){
$scope.remainingTime = $scope.remainingTime - 1;
if($scope.remainingTime==0){
//$interval.cancel($scope.timeInterval);
$scope.remainingTime=60;
}
}, 1000);
}]);
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="timerApp" ng-controller="timerController">
<div >{{remainingTime}}</div>
</div>
</body>

Related

angular timer - .stop() and .resume() problems

I'm having a bit trouble with my timer. I might have made it more complicated than it should be because what I need is the following:
I need to count from 00:00 to say 45:00 and I need to be able to stop and resume the timer within these boundaries.
Right now I've got this timer code:
<timer id="timer" autostart="false" start-time="coutingStart" end-time="countingEnd">{{mminutes}}:{{sseconds}}</timer>
countingStart and countingEnd initializes like this:
var time = (45 * 60000); // should give me 45 minutes of time.
$scope.countingStart = (new Date()).getTime();
$scope.countingEnd = (new Date()).getTime() + time;
This code above works, atleast I think it does.
I've got a button with this function on it:
$scope.startGame = function() {
$scope.gameIsLive = true;
document.getElementById('timer').start();
};
which starts my counter, no problem, it starts from 00:00 atleast.
But then I have buttons with these functions aswell which is where I'm having my problem.
$scope.PauseGame = function() {
switch ($scope.periodNum) {
case 1:
document.getElementById('timer').stop();
$scope.PauseIsActive = true;
break;
case 2:
document.getElementById('timer').stop();
$scope.PauseIsActive = true;
break;
}
};
$scope.ResumeGame = function() {
switch ($scope.periodNum) {
case 1:
document.getElementById('timer').resume();
$scope.PauseIsActive = false;
break;
case 2:
document.getElementById('timer').resume();
$scope.PauseIsActive = false;
break;
}
};
Both pauseGame() and resumeGame() works as expected. They are pausing and resuming the timer. But, when I pause the timer on say 00:10 and count for myself 10 seconds and then resume it the timer now stands on 00:20 which made me just lost 10 seconds of the timer.
I can think that my problem is inside the instantiating of $scope.counterStart and $scope.counterEnd. But I am not sure. How can I count from 00:00 to 45:00 and still being able to stop and resume the clock when needed?
Angular timer uses the Date object and milliseconds to count time so I suppose I have to use this approach to get 00:00 which is now and count 45 minutes forward. Can it be done otherwise with stop and resume functionality?
Thanks.
If I understand the angular-timer docs end-time sets the countdown time. It doesn't provide a maximum value.
end-time Sets the countdown based on predefined end time (in
milliseconds).
To have a maximum value you can check each tick event to see if the configured maximum value has been reached. I have created an example below in which the timer is stopped when it reaches the maximum value (10 seconds).
(function() {
angular
.module('exampleApp', ['timer'])
.controller('ExampleController', ExampleController);
function ExampleController($scope, TimerStatusEnum, $timeout) {
var vm = this;
vm.max = 10000; // 10 seconds
vm.isMaxReached = false;
vm.timerStatus = TimerStatusEnum.NotStarted;
vm.startTimer = function() {
if (!vm.isMaxReached) {
if (vm.timerStatus === TimerStatusEnum.NotStarted) {
$scope.$broadcast('timer-start');
vm.timerStatus = TimerStatusEnum.Running
} else if (vm.timerStatus === TimerStatusEnum.Stopped) {
$scope.$broadcast('timer-resume');
vm.timerStatus = TimerStatusEnum.Running
}
}
};
vm.stopTimer = function() {
if (vm.timerStatus === TimerStatusEnum.Running) {
$scope.$broadcast('timer-stop');
vm.timerStatus = TimerStatusEnum.Stopped
}
};
vm.isTimerStopped = function() {
return vm.timerStatus === TimerStatusEnum.Stopped;
}
vm.isTimerRunning = function() {
return vm.timerStatus === TimerStatusEnum.Running;
}
$scope.$on('timer-tick', function(event, args) {
var roundedMiliSecondCount = Math.round(args.millis / 1000) * 1000;
if (roundedMiliSecondCount === vm.max) {
$timeout(function() {
vm.isMaxReached = true;
vm.stopTimer();
}, 0);
}
});
}
ExampleController.$inject = ['$scope', 'TimerStatusEnum', '$timeout'];
})();
(function() {
angular
.module('exampleApp')
.constant('TimerStatusEnum', {
'NotStarted': 0,
'Stopped': 1,
'Running': 2
});
})();
<!DOCTYPE html>
<html ng-app='exampleApp'>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-timer/1.3.4/angular-timer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/humanize-duration/3.9.1/humanize-duration.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js"></script>
</head>
<body ng-controller="ExampleController as vm">
<timer id="timer" autostart="false" interval="1000">{{mminutes}}:{{sseconds}}</timer>
<button ng-click="vm.startTimer()" ng-disabled="vm.isTimerRunning() || vm.isMaxReached">Start Timer</button>
<button ng-click="vm.stopTimer()" ng-disabled="vm.isTimerStopped() || vm.isMaxReached">Stop Timer</button>
<p ng-if="vm.isMaxReached">Max time has been reached</p>
</body>
</html>

How to change the interval dynamically when using setInterval

I have this fiddle : https://jsfiddle.net/reko91/stfnzoo4/
Im currently using Javascripts setInterval() to log a string to console.
What I want to do, is in this setInterval function check whether the interval variable has changed, if it has, change the interval in the setInterval function. I can lower the interval variable by 100 (speeding the function up) by a click a button.
Is this possible ?
Someone mentioned this : Changing the interval of SetInterval while it's running
But this is using a counter, so they only run it a certain amount of times. I need to run it for however long, but change how fast the function gets called again.
Here is the code :
var interval = 2000;
setInterval(function() {
interval = getInterval();
console.log('interval')
}, interval);
function getInterval() {
return interval;
}
$('#speedUp').on('click', function() {
interval -= 100;
console.log(interval)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='speedUp'>
speed up
</button>
I would just stop the interval and start a new one with the different timing
var interval = 2000;
var intervalId;
// store in a function so we can call it again
function startInterval(_interval) {
// Store the id of the interval so we can clear it later
intervalId = setInterval(function() {
console.log(_interval);
}, _interval);
}
function getInterval() {
return interval;
}
$('#speedUp').on('click', function() {
interval -= 100;
// clear the existing interval
clearInterval(intervalId);
// just start a new one
startInterval(interval);
console.log(interval)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='speedUp'>
speed up
</button>

$interval continues to run when I go from one state to other using route

I have a application in which I have to show a page time-out timer progress bar. I am doing it using $interval. But When I go from one state to other the $interval doesn't get cleared and the shows the session time-out of the previous page. I am using the $interval function in a controller for timer functionality. I am also cancelling the same on page destroy. here is the below snippet,
$scope.obj.updateProgressBar = function () {
$scope.obj.showTimer = true;
intervalPromise = $interval(function () {
if ($scope.obj.currentTime < $scope.obj.max) {
$scope.obj.currentTime += 1;
$scope.obj.diff = $scope.obj.max - $scope.obj.currentTime;
$scope.obj.m = ($scope.obj.diff / 60) >> 0;
$scope.obj.s = ($scope.obj.diff - $scope.obj.m * 60) + '';
$scope.obj.s = ($scope.obj.s).length >= 1 ? $scope.obj.s : '0';
} else {
$scope.obj.timeout=true;
$interval.cancel(intervalPromise);
$scope.togglePopup();
$scope.open('sm', 'sessionTimeoutTemplate');
}
}, 1000,timerDuration+1);
};
$scope.obj.updateProgressBar();
}
$scope.$on('$destroy',function(){
if(intervalPromise)
$interval.cancel(intervalPromise);
});
Please help me on this, what i can do to destroy the $interval.
Thanks,
Tushar

How to clear or stop timeInterval in angularjs?

I am making a demo in which I am fetching data from the server after regular intervals of time using $interval Now I need to stop/cancel this.
How I can achieve this? If I need to restart the process, how should I do that?
Secondly, I have one more question: I am fetching data from the server after reqular intervals of time. Is there any need to use $scope.apply or $scope.watch?
Here is my plunker:
app.controller('departureContrl',function($scope,test, $interval){
setData();
$interval(setData, 1000*30);
function setData(){
$scope.loading=true;
test.stationDashBoard(function(data){
console.log(data);
$scope.data=data.data;
$scope.loading=false;
//alert(data);
},function(error){
alert('error')
}) ;
}
});
http://plnkr.co/edit/ly43m5?p=preview
You can store the promise returned by the interval and use $interval.cancel() to that promise, which cancels the interval of that promise. To delegate the starting and stopping of the interval, you can create start() and stop() functions whenever you want to stop and start them again from a specific event. I have created a snippet below showing the basics of starting and stopping an interval, by implementing it in view through the use of events (e.g. ng-click) and in the controller.
angular.module('app', [])
.controller('ItemController', function($scope, $interval) {
// store the interval promise in this variable
var promise;
// simulated items array
$scope.items = [];
// starts the interval
$scope.start = function() {
// stops any running interval to avoid two intervals running at the same time
$scope.stop();
// store the interval promise
promise = $interval(setRandomizedCollection, 1000);
};
// stops the interval
$scope.stop = function() {
$interval.cancel(promise);
};
// starting the interval by default
$scope.start();
// stops the interval when the scope is destroyed,
// this usually happens when a route is changed and
// the ItemsController $scope gets destroyed. The
// destruction of the ItemsController scope does not
// guarantee the stopping of any intervals, you must
// be responsible for stopping it when the scope is
// is destroyed.
$scope.$on('$destroy', function() {
$scope.stop();
});
function setRandomizedCollection() {
// items to randomize 1 - 11
var randomItems = parseInt(Math.random() * 10 + 1);
// empties the items array
$scope.items.length = 0;
// loop through random N times
while(randomItems--) {
// push random number from 1 - 10000 to $scope.items
$scope.items.push(parseInt(Math.random() * 10000 + 1));
}
}
});
<div ng-app="app" ng-controller="ItemController">
<!-- Event trigger to start the interval -->
<button type="button" ng-click="start()">Start Interval</button>
<!-- Event trigger to stop the interval -->
<button type="button" ng-click="stop()">Stop Interval</button>
<!-- display all the random items -->
<ul>
<li ng-repeat="item in items track by $index" ng-bind="item"></li>
</ul>
<!-- end of display -->
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
var interval = $interval(function() {
console.log('say hello');
}, 1000);
$interval.cancel(interval);
var promise = $interval(function(){
if($location.path() == '/landing'){
$rootScope.$emit('testData',"test");
$interval.cancel(promise);
}
},2000);
When you want to create interval store promise to variable:
var p = $interval(function() { ... },1000);
And when you want to stop / clear the interval simply use:
$interval.cancel(p);
$scope.toggleRightDelayed = function(){
var myInterval = $interval(function(){
$scope.toggleRight();
},1000,1)
.then(function(){
$interval.cancel(myInterval);
});
};

Stop time interval during navigation in angularjs

Currently i am using angular js
I have one get method to get data from server side in default.html page
function bindActiveLoans() {
$http.get(rootUrlSingleEscaped + '/cooperativa/allunfundedloans/?authId=' + userInfo.UserId)
.success(function (response) {
if (response.Loans.length == 0) {
$scope.IsValues = false;
$scope.$apply();
return true;
}
$scope.IsValues = true;
$scope.unfundedLoans = response;
});
};
setInterval(function () {
$scope.$apply(bindActiveLoans());
}, 5000);
The above function helps to get the data from server side method in every 5 seconds.
Here, I have an issue.
Additionally I have some more pages, like
default2.html,default3.html,default4.html,default5.html.
The timer is still running while i navigation default.html page to default1.html page. I want to only that timer running in default.html page.If i go to another page,then the timer should stop. How can we achieve it?
From the angularjs example in the $interval API page.
var interval = $interval(function() {
console.log('say hello');
}, 1000);
$interval.cancel(interval);
With $interval.cancel(var) you can stop the interval and if you want to stop it when navigating to another page you should try something like this.
var interval = null;
module.controller('SomeController', '$interval', function($interval) {
interval = $interval(function() {
...
}, 2000);
}).run(['$rootScope', '$interval', function($rootScope, $interval) {
$rootScope.$on('$routeChangeStart', function() {
$interval.cancel(interval);
});
}]);
You can listen to the $routeChangeStart event and do the clearing of the interval depending on the route parameters,
$scope.$on('$routeChangeStart', function (scope, next, current) {
if(<next is not default.aspx>){
// clear interval here
}
});
call clearInterval function when navigating from default page
e.g.
var myVar = setInterval(function () {
$scope.$apply(bindActiveLoans());
}, 5000);
function myStopFunction()
{
clearInterval(myVar);
}
Call myStopFunction

Categories