4

I want to create a stop watch. I googled and got a few tips on how to make a timer. Here is what I have done in my controller:

$scope.value = 0;
$scope.startTimer = function() {

     $scope.value = 0;

    var change = function() {
        $scope.value += 1000;
        $timeout(change,1000);
    };
    $timeout(change, 1000);
}

And in my html displayed value in this format:

<label>{{value | date: 'hh:mm:ss'}}</label>

The problem is the clock always starts at 04:00:00 and when I call the startTimer() function, it starts the timer okay but I want the timer to be like:

00:00:00

00:00:01

00:00:02

....

Can anyone tell me how to start timer at 00:00:00?

Sibtain
  • 1,436
  • 21
  • 39

1 Answers1

5

EDITED: Updated code with interval timer, so now code contains both timers with $timeout and $interval.
Here you go, make your own filter:

var app = angular.module("myApp",[]);
app.controller("myController",function($scope, $timeout, $interval){
   
   //timer with timeout
   $scope.timerWithTimeout = 0;
   $scope.startTimerWithTimeout = function() {
    $scope.timerWithTimeout = 0;
    if($scope.myTimeout){
      $timeout.cancel($scope.myTimeout);
    }
    $scope.onTimeout = function(){
        $scope.timerWithTimeout++;
        $scope.myTimeout = $timeout($scope.onTimeout,1000);
    }
    $scope.myTimeout = $timeout($scope.onTimeout,1000);
  };
  
  $scope.resetTimerWithTimeout = function(){
    $scope.timerWithTimeout = 0;
    $timeout.cancel($scope.myTimeout);
  }
  
  //timer with interval
  $scope.timerWithInterval = 0;
   $scope.startTimerWithInterval = function() {
    $scope.timerWithInterval = 0;
    if($scope.myInterval){
      $interval.cancel($scope.myInterval);
    }
    $scope.onInterval = function(){
        $scope.timerWithInterval++;
    }
    $scope.myInterval = $interval($scope.onInterval,1000);
  };
  
  $scope.resetTimerWithInterval = function(){
    $scope.timerWithInterval = 0;
    $interval.cancel($scope.myInterval);
  }
})
app.filter('hhmmss', function () {
  return function (time) {
    var sec_num = parseInt(time, 10); // don't forget the second param
    var hours   = Math.floor(sec_num / 3600);
    var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
    var seconds = sec_num - (hours * 3600) - (minutes * 60);

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}
    var time    = hours+':'+minutes+':'+seconds;
    return time;
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myController">
  <label>Timer with timeout: {{timerWithTimeout | hhmmss}}</label>
  <button ng-click="startTimerWithTimeout()">Start Timer</button>
  <button ng-click="resetTimerWithTimeout()">reset tiemr</button>
  <br><br>
  <label>Timer with interval: {{timerWithInterval | hhmmss}}</label>
  <button ng-click="startTimerWithInterval()">Start Timer</button>
  <button ng-click="resetTimerWithInterval()">reset tiemr</button>
</div>

Addition: For timer it is better to use $interval instead of $timeout. and always reference $interval to some variable :$scope.timer = $interval(change, 1000); , so you can destroy it on each reset:$interval.cancel($scope.timer); .

Mudasser Ajaz
  • 6,197
  • 1
  • 26
  • 29
  • Thank you! Worked like a charm – Sibtain Aug 29 '15 at 12:21
  • @Sibtain , i also made few changes, and added some helpful notes related to $timeout and $interval use. – Mudasser Ajaz Aug 29 '15 at 12:42
  • Thanks. Can I use $timeout to stop the timer? – Sibtain Aug 29 '15 at 12:44
  • 1
    yes you can in same way. `$scope.timer = $timeout(change,1000);` then `$interval.cancel($scope.timer);` – Mudasser Ajaz Aug 29 '15 at 12:55
  • @mudasserajaz can you change the code to use $interval? – Piet Sep 02 '15 at 06:41
  • @Piet i am going to add interval version to this. – Mudasser Ajaz Sep 02 '15 at 06:49
  • this works like a charm, thank you, but I have 1 big issue: I need 10 different timers, which I can start and stop independent each others. With this code I start all and stop all with 1 click – Piet Sep 02 '15 at 20:11
  • I used the code I linked here http://stackoverflow.com/questions/32319327/change-the-update-interval-which-is-shown?noredirect=1#comment52514408_32319327 and added the filter from your code. Its working now like I want, with the possibility of dynamic numbers of watches – Piet Sep 02 '15 at 20:59
  • @MudasserAjaz - I know this is from awhile ago, but found this useful. Only one problem I have and I have asked it on this thread: http://stackoverflow.com/questions/37707546/angular-directive-to-directive-communication-for-timer – pertrai1 Jun 08 '16 at 16:30
  • @MudasserAjaz I could not understand how its checking for 60 seconds and then moving to minute counter, please can you comment the logic, I am struggling to getthis. – sac Dahal Oct 05 '16 at 10:08
  • @sacDahal it does not check for 60 second, in-fact it checks every second which is done by this line `$scope.myInterval = $interval($scope.onInterval,1000);` 1000 is ms = 1 s – Mudasser Ajaz Oct 05 '16 at 11:46