Here is my angular code to define a countdown timer for my website:
function AlbumCtrl($scope, $timeout) {
$scope.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
$scope.onTimeout = function() {
$scope.counter--;
var distance = $scope.counter;
$scope.countdown = Math.floor(distance / (1000 * 60 * 60 * 24)) + "d " +
Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + "h " +
Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + "m " +
Math.floor(((distance % (1000 * 60)) / 1000)) + "s ";
if ($scope.counter > 0) {
mytimeout = $timeout($scope.onTimeout, 1000);
} else {
alert("Time is up!");
}
}
var mytimeout = $timeout($scope.onTimeout, 1000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <!-- added for a working snippet -->
<!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}} {{countdown}}
</div>
</body>
</html>
The 'counter' appears to decrement correctly on my page but the 'countdown' stays fixed and shows the correct value only on page load or refresh. For example, I get the following output as time passes:
1115148833 12d 21h 45m 48s
1115148745 12d 21h 45m 48s
1115148693 12d 21h 45m 48s
What exactly is going wrong?
https://github.com/johnpapa/angular-styleguide/tree/master/a1
// Declare a "main" module for the single page application
// second argument to module is an array of dependencies your module
// uses (examples: ui-router ui-bootstrap etc., 'ng' module is assumed as a dependency)
angular.module('myApp', [])
//Defining a service on the module allows you to encapsulate some functionality
//Injecting the angular $timeout service from the 'ng' module and defining
//a new service. This object gets initialized the first time it's
//referenced and stays alive until the application/page is refreshed.
.service("CountdownService", function($timeout){
//Define an object to attach properties and functions to and return for
//use elsewhere in the app
var countdownService = {};
//Basically the functional code you had already adjusted the
//seconds to just use %60 since some sort of issue with the existing math
// %60 should give remainder after dividing by 60 and appears the "distance"
// was moving at 1 second per second not 1000, so removed the 1000 factors
countdownService.counter = new Date("Nov 30, 2017 09:00:00").getTime() - new Date().getTime();
countdownService.onTimeout = function() {
countdownService.counter--;
var distance = countdownService.counter;
var newValue = Math.floor(distance / (1000 * 60 * 60 * 24)) + "d " +
Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)) + "h " +
Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) + "m " +
Math.floor((distance % (60)) ) + "s ";
countdownService.countdown = newValue;
console.log(Math.floor((distance % (60))) + "s ");
if (countdownService.counter > 0) {
mytimeout = $timeout(countdownService.onTimeout, 1000);
} else {
alert("Time is up!");
}
}
var mytimeout = $timeout(countdownService.onTimeout, 1000);
return countdownService;
})
//Now the controller just has the new service injected it uses "this"
//instead of scope in the ng-controller we use "controllerAs" syntax
//so we don't need to use the scope (angular 2 hides the scope so good
//to just get used to not using it)
.controller("TestCtrl", function(CountdownService){
this.CountdownService = CountdownService;
});
<!doctype html>
<html ng-app="myApp">
<head>
</head>
<body>
<div ng-controller="TestCtrl as testCtrl">
{{testCtrl.CountdownService.counter}} {{testCtrl.CountdownService.countdown}}
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script> <!-- added for a working snippet -->
</body>
</html>