2

I've got what I thought was a fairly simple AngularJS application. I used to have a simple countdown timer in my controller code, but I decided to break it out into its own service. That's where the problems began.

Previously, when my timer code was embedded within the controller, the countdown scope variable displayed correctly - every second, it would count down one less, until 0, as per the timer function. However, now that I've moved this to a service, and been passing the data back and forth with some function calls, the countdownvariable counts down 2 numbers every second, rather than 1. If I console.log(countdown); in my service's rundownClock() function, the correct countdown number is displayed each pass, however: 10,9,8,7...to 1.

Can anyone figure out what I'm now doing wrong, and why this "double counting" is occurring? Am I not maintaining the scope correctly in the controller?

Here is some of the controller, with the relevant CountdownService bits highlighted:

myApp.controller('myCtrl', ['$scope', 'CountdownService', function($scope, CountdownService) {

    // TIMER SERVICES
    $scope.startTimer = CountdownService.startTimer;

    $scope.runClock = function () {

        $scope.updateCountdown();

        if (($scope.countdown > 0) && ($scope.roundStarted == true)) {
            CountdownService.rundownClock($scope.countdown);
        }
    };

    $interval($scope.runClock, 1000);

    $scope.updateCountdown = function () {

        CountdownService.setCurrentRound($scope.currentRound);
        $scope.countdown = CountdownService.getCountdown();
        $scope.roundStarted = CountdownService.getRoundStarted();

    }

    }]);

Here's some of the service in question. (Don't worry about the rounds variable set-up at the beginning, it's not relevant to the problem):

myApp
    .factory("CountdownService", function (gameSetUp) {

        var rounds = gameSetUp.rounds,
            roundStarted = false,
            roundFinished = false,
            currentRound = 0,
            countdown = rounds[currentRound].time;

        // grab the round from the controller's scope to set the current round
        function setCurrentRound(round) {
            currentRound = round;
        }

        function getRoundStarted() {
            return roundStarted;
        }

        function getCountdown() {
            return countdown;
        }

        function startTimer() {
            roundStarted = true;
        }

        function rundownClock() {

            if (roundStarted === true) {

                if (countdown > 0) {
                    countdown = countdown - 1;
                }

                if (countdown === 0) {
                    roundFinished = true;
                }
            }
        }

        return {
            startTimer: startTimer,
            rundownClock: rundownClock,
            getCountdown: getCountdown,
            getRoundStarted: getRoundStarted,
            setCurrentRound: setCurrentRound
        };
    });

And finally, a snippet from the view, where the countdown scope variable is displayed:

<div class="timer md-body-2">{{ countdown }} seconds</div>
7
  • Shouldn'y in Controller be CountdownService.startTimer()? Commented Sep 16, 2015 at 14:57
  • What about to use "new Date().getTime() / 1000" to store the initial second, and to get elapsed seconds? Commented Sep 16, 2015 at 15:00
  • @cyan no, since that is actually called onClick by a different part of the view. A little odd, but it's how it works... :) Commented Sep 16, 2015 at 15:02
  • rundownClock has no parameter but is called with parameter. Commented Sep 16, 2015 at 15:05
  • @JoaozitoPolo yeah, I prob should have started with using elapsed time, but I did it the way I did it .. would appreciate any advice on why the data is out of sync b/w the controller and service though. any clue? Commented Sep 16, 2015 at 15:06

1 Answer 1

1

Update @downvoter :

Here is a working demo ( without using controller in 2 places route and template)

Here is the exact behavior that the author is talking about (using controller in route and template)

My original answer

I think your myCtrl controller is running twice, so, your $interval($scope.runClock, 1000); is running twice also ...

Are using registering myCtrl as route controller and in your template with ng-controller ?

Sign up to request clarification or add additional context in comments.

1 Comment

Ah! Now I see what you're saying, and you're completely right. :) I was using ng-controller=myCtrl" as well as the ng-view. Problem solved! Life saver!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.