angularjs make a simple countdown

132,681

Solution 1

Please take a look at this example here. It is a simple example of a count up! Which I think you could easily modify to create a count down.

http://jsfiddle.net/ganarajpr/LQGE2/

JavaScript code:

function AlbumCtrl($scope,$timeout) {
    $scope.counter = 0;
    $scope.onTimeout = function(){
        $scope.counter++;
        mytimeout = $timeout($scope.onTimeout,1000);
    }
    var mytimeout = $timeout($scope.onTimeout,1000);

    $scope.stop = function(){
        $timeout.cancel(mytimeout);
    }
}

HTML markup:

<!doctype html>
<html ng-app>
<head>
    <script src="http://code.angularjs.org/angular-1.0.0rc11.min.js"></script>
    <script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
</head>
<body>
<div ng-controller="AlbumCtrl">
    {{counter}}
    <button ng-click="stop()">Stop</button>    
</div>
</body>
</html>

Solution 2

As of version 1.3 there's a service in module ng: $interval

function countController($scope, $interval){
    $scope.countDown = 10;    
    $interval(function(){console.log($scope.countDown--)},1000,0);
}​​

Use with caution:

Note: Intervals created by this service must be explicitly destroyed when you are finished with them. In particular they are not automatically destroyed when a controller's scope or a directive's element are destroyed. You should take this into consideration and make sure to always cancel the interval at the appropriate moment. See the example below for more details on how and when to do this.

From: Angular's official documentation.

Solution 3

You should use $scope.$apply() when you execute an angular expression from outside of the angular framework.

function countController($scope){
    $scope.countDown = 10;    
    var timer = setInterval(function(){
        $scope.countDown--;
        $scope.$apply();
        console.log($scope.countDown);
    }, 1000);  
}

http://jsfiddle.net/andreev_artem/48Fm2/

Solution 4

I updated Mr. ganaraj answer to show stop and resume functionality and added angular js filter to format countdown timer

it is here on jsFiddle

controller code

'use strict';
var myApp = angular.module('myApp', []);
myApp.controller('AlbumCtrl', function($scope,$timeout) {
    $scope.counter = 0;
    $scope.stopped = false;
    $scope.buttonText='Stop';
    $scope.onTimeout = function(){
        $scope.counter++;
        mytimeout = $timeout($scope.onTimeout,1000);
    }
    var mytimeout = $timeout($scope.onTimeout,1000);
    $scope.takeAction = function(){
        if(!$scope.stopped){
            $timeout.cancel(mytimeout);
            $scope.buttonText='Resume';
        }
        else
        {
            mytimeout = $timeout($scope.onTimeout,1000);
            $scope.buttonText='Stop';
        }
            $scope.stopped=!$scope.stopped;
    }   
});

filter-code adapted from RobG from stackoverflow

myApp.filter('formatTimer', function() {
  return function(input)
    {
        function z(n) {return (n<10? '0' : '') + n;}
        var seconds = input % 60;
        var minutes = Math.floor(input / 60);
        var hours = Math.floor(minutes / 60);
        return (z(hours) +':'+z(minutes)+':'+z(seconds));
    };
});

Solution 5

The way I did , it works!

  • *angular version 1.5.8 and above.

Angular code

var app = angular.module('counter', []);

app.controller('MainCtrl', function($scope, $interval) {
  var decrementCountdown = function() {
    $scope.countdown -= 1;
    if ($scope.countdown < 1) {
      $scope.message = "timed out";
    }
  };
  var startCountDown = function() {
    $interval(decrementCountdown, 1000, $scope.countdown)
  };
  $scope.countdown = 100;
  startCountDown();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.10/angular.min.js"></script>



<body ng-app="counter" ng-controller="MainCtrl">
  {{countdown}} {{message}}
</body>
Share:
132,681
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    I would like make a countDown with Angular js. this is my code:

    Html File

    <div ng-app ng-controller = "countController"> {{countDown}} <div>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
    

    js File

    function countController($scope){
        $scope.countDown = 10;    
        var timer = setInterval(function(){$scope.countDown--; console.log($scope.countDown)},1000);  
    }​​
    

    in console.log it works I have a countdown but in {{countdown}} refresh it doesn't could you help me please? thanks!

  • ganaraj
    ganaraj over 11 years
    Directly using setTimeOut or setInterval is not a good practice in Angular. You should be using the $timeout service.
  • Daniel
    Daniel over 11 years
    Here is a modification that does a count down: jsfiddle.net/dpeaep/LQGE2/1
  • Artem Andreev
    Artem Andreev over 11 years
    @ganaraj It depends on the task. Practicality beats purity.
  • pkozlowski.opensource
    pkozlowski.opensource over 11 years
    There is the $timeout service in AngularJS that would call $apply automatically.
  • Artem Andreev
    Artem Andreev over 11 years
    @pkozlowski.opensource Thanks, you didn't say anything new. I am able to read answers and comments :) I think that it is good to have two answers. One explains why code doesn't work and how you can make it work. And another that explains how it could be done in more angular way.
  • guy mograbi
    guy mograbi about 11 years
    Your answer is much better. You are using interval which is much more suitable for a counter.
  • Dipesh KC
    Dipesh KC over 10 years
    @ganaraj can you give show the code to achieve the same with $timeout service?
  • Hakan B.
    Hakan B. about 10 years
    Thanks. For anyone else wondering, this isn't limited to 1.3: code.angularjs.org/1.2.12/docs/api/ng.$interval
  • Andres
    Andres over 9 years
    good, I used $interval instead of $timeout
  • CodyBugstein
    CodyBugstein almost 9 years
    How would you stop the clock?
  • Bobby Stenly
    Bobby Stenly over 7 years
    I don't think the format timer is return the correct answer.. Let say the input is 7200. it would return 02:120:00. I think you should format the timer by calculating hour first.
  • jaycer
    jaycer over 7 years
    Agree with @Andres - I feel $interval is the way to go. This is the answer I eventually used for an angularjs timer implementation.
  • Admin
    Admin almost 6 years
    The code is pretty straight forward if you look up $interval usage here docs.angularjs.org/api/ng/service/$interval. $interval starts a service that decreases countDown every seconds (ie. 1000 = 1sec), and the third parameter tells it to do it 10x (since $scope.countDown initial value is 10).