I'm new to programming, and have recently been playing around with AngularJS.
To practice, i've decided try and create a simple stopwatch.
Starting with an initial 'time' value of 0, i'm using $interval to increment the 'time' by 0.01, every 10 milliseconds. I can start and stop the stopwatch without any issues, UNLESS i click 'Start' twice. After doing so, 'Stop' no longer works.
I'm sure this is an awful way to create a stopwatch, but regardless, the issue still remains.
My html contains the timer and 'Start' and 'Stop' buttons, like so:
<div class="row" style="margin-left: 20px" ng-controller="timerCtrl">
<b>{{time | number : 2}}</b>
<button ng-click="startTimer()">Start</button>
<button ng-click="stopTimer()">Stop</button>
</div>
And the js:
.controller('timerCtrl', ['$scope', '$timeout', '$interval',
function($scope, $timeout, $interval) {
$scope.time = 0;
$scope.startTimer = function() {
$scope.counter = $interval(function(){
$scope.time += 0.01;
}, 10)
}
$scope.stopTimer = function() {
$interval.cancel($scope.counter);
}
}
])
What's the best way to solve this? Any help will be much appreciated, thanks!
The problem is that $interval
returns a promise, and each time you run $scope.startTimer
you are creating a new promise. When you run it a second time, it doesn't cancel the previous promise, it just re-assigns $scope.counter
to the new promise.
Check out the AngularJS $interval page to see their example and method of avoiding this problem.
A simple solution is to check to see whether the var you're assigning your promise to has already been defined when you are about to create a new promise. For example:
if ( angular.isDefined($scope.counter) ) return;
You can also use a boolean var to maintain the status as to whether it has been started or not if you prefer that.