1

So I'm creating a simple countdown function in AngularJS which is mean to count down to the time set in inputs. The problem is that I'm not able to loop the $scope.countdown function. So it only counts down once (and if I put the $timeout($scope.countdown(), 1000); in - it breaks entirely.) I just want it to loop every second until it reaches 0.

Here's my controller:

function countdownController($scope) {

  $scope.hours = 2;
  $scope.minutes = 30;

  $scope.countdown = function(){
    if($scope.minutes == 0 && $scope.hours == 0){
        alert('end!');
        return;
    }
    else{
        if($scope.minutes == 0){
            $scope.minutes = 59;
            $scope.hours--;
        }
        else{
            $scope.minutes--;
        }

    }
    $timeout($scope.countdown(), 1000); //if I remove this - the numbers display - this actually breaks that.
  }

  $scope.countdown();
}
itamar
  • 3,837
  • 5
  • 35
  • 60
  • I think you want to be passing the function not executing the function $timeout($scope.countdown, 1000); – Matt Pileggi Mar 11 '14 at 16:21
  • @MattPileggi Can you show me where in the app to put it? I think that's what I'm missing. Thanks! – itamar Mar 11 '14 at 16:52
  • You have it in there where you put the comment about removing it. Just change that line so that it's not invoking $scope.countdown but passing it as an object instead. – Matt Pileggi Mar 11 '14 at 17:08
  • @MattPileggi I'm confused about syntax and how I can pass it as an object. Do I put it like this? `$timeout(1000){$scope.countdown()};` I'm sure that's wrong but showing you where I'm getting lost. Thanks! – itamar Mar 11 '14 at 17:35

2 Answers2

3

What you're looking for is arguments.callee :

$scope.countdown = function(){
    if($scope.minutes == 0 && $scope.hours == 0){
        alert('end!');
        return;
    }
    else{
        if($scope.minutes == 0){
            $scope.minutes = 59;
            $scope.hours--;
        }
        else{
            $scope.minutes--;
        }

    }
    $timeout(arguments.callee, 1000);
}

Or its more advised alternative :

function countdownController($scope, $timeout) {
    $scope.hours = 0;
    $scope.minutes = 45;
    $scope.countdown = function myhandler() {
        console.log('call');
        if ($scope.minutes == 0 && $scope.hours == 0) {
            console.log('end!');
            return;
        } else {
            if ($scope.minutes == 0) {
                $scope.minutes = 59;
                $scope.hours--;
            } else {
                $scope.minutes--;
            }

        }
        $timeout(myhandler, 1000);
    }
}

JsFiddle Example

NB : as mentionned in the comments, don't forget to inject $timeout into your controller.

Community
  • 1
  • 1
Florian F.
  • 4,700
  • 26
  • 50
  • Thanks for this but for some reason `$timeout(myhandler, 1000);` breaks the app. The calling of it in $timeout - not the naming of he function on top. That's fine. – itamar Mar 11 '14 at 16:51
  • What does "breaks the app" actually mean ? – Florian F. Mar 12 '14 at 06:21
  • 1
    It works to me, updated with a [jsfiddle example](http://jsfiddle.net/floo51/HB7LU/2427/). – Florian F. Mar 12 '14 at 10:20
  • ah! I didn't include $timeout in the MyCtrl function with $scope. Now it works great. Thanks! Can you update your answer to include exactly what you have in the JSFiddle so that I can mark it as correct? Thanks! – itamar Mar 12 '14 at 13:41
  • @itamar Updated with the timeout injection – Florian F. Mar 12 '14 at 15:12
0

You have to pass a function to the $timeout service. NOT the result of the function. Try this:

$timeout($scope.countdown, 1000); 
Michael
  • 3,085
  • 1
  • 17
  • 15
  • But where? As you can see I already have exactly that at the end of my $scope.countodwn function. – itamar Mar 11 '14 at 16:50