Reputation: 887
Basically I have copied this code from another source which is a countdown timer.
Directive
app.directive('countdown', [
'Util', '$interval', function (Util, $interval) {
return {
restrict: 'E',
scope: {
date: '@'
},
templateUrl: 'countdown_timer.html',
link: function (scope, element) {
var future = new Date(scope.date);
var stop;
stop = $interval(function () {
var diff;
diff = Math.floor((future.getTime() - new Date().getTime()) / 1000);
if (parseInt(diff) <= 0) {
stopTimer();
scope.days = 0;
scope.hours = 0;
scope.minutes = 0;
scope.seconds = 0;
} else {
var d = Util.dhms(diff);
scope.days = d[0];
scope.hours = d[1];
scope.minutes = d[2];
scope.seconds = d[3];
}
}, 1000);
stopTimer = function () {
console.log("Should Stop");
$interval.cancel(stop);
};
}
};
}
]).factory('Util', [
function () {
return {
dhms: function (t) {
var days, hours, minutes, seconds;
days = Math.floor(t / 86400);
t -= days * 86400;
hours = Math.floor(t / 3600) % 24;
t -= hours * 3600;
minutes = Math.floor(t / 60) % 60;
t -= minutes * 60;
seconds = t % 60;
return [days, hours, minutes, seconds];
}
};
}
]);
HTML
<div class="col-xs-12" ng-repeat="event in events">
<countdown date="{{ event.event_date }}"></countdown>
</div>
TEMPLATE
<div class='time_division_container'>
<div class='digits_container'>{{ days }}</div>
<div class='label_container'>DAYS</div>
</div>
<div class='time_division_container'>
<div class='digits_container'>{{ hours }}</div>
<div class='label_container'>HOURS</div>
</div>
<div class='time_division_container'>
<div class='digits_container'>{{ minutes }}</div>
<div class='label_container'>MINUTES</div>
</div>
<div class='time_division_container'>
<div class='digits_container'>{{ seconds }}</div>
<div class='label_container'>SECONDS</div>
</div>
This works fine at first if the countdown is only 1. But when I add multiple event_date in the event object the
$interval.cancel(stop);
seems not working.
For example if I have these event dates
var events = {
{"event_date" : "2017-11-30 12:00:00"},
{"event_date" : "2017-11-01 09:00:00"}
};
The first date is working fine but the second date which has already passed is not stopping its countdown. If you look at the console log it still displays "Should Stop" multiple times. It should only display once since I made and if statement that calls the "stopTimer" function when the difference of the current time and the event date is 0 or negative.
Please help. Thanks a lot.
Upvotes: 0
Views: 964
Reputation: 1147
You have a scoping problem. stopTimer
is being defined as a global variable, and each time the directive instantiates it overwrites the previous definition. So when you call stopTimer
from the first directive, it calls the stopTimer
defined in the second directive, who's stop
variable is pointing to something else. Also, probably a typo in your question, but events
should be an array for ng-repeat
to work.
If you change:
stopTimer = function () {
console.log("Should Stop");
$interval.cancel(stop);
};
to
var stopTimer = function () {
console.log("Should Stop");
$interval.cancel(stop);
};
it works correctly, as stopTimer
is now scoped. See the attached plunkr: https://plnkr.co/edit/41DlPAP07iBtmAq3kKbR
Aside, it's useful to enable strict
mode to avoid scoping problems like this. See What does "use strict" do in JavaScript, and what is the reasoning behind it?. If strict mode were enabled, you would have seen an error in your console.
Upvotes: 1