I am new to Angular (and JS) and just a little confused.
I start a timer with :
var getOverviewMapTimer = $interval($scope.UpdateOverviewMap, UPDATE_FREQUENCY);
and, if I understand it, getOverviewMapTimer
is a "promise".
I want to be able to check if the timer is running & had excepted that if I ever
$interval.cancel(getOverviewMapTimer);
then getOverviewMapTimer
would be null
and I could check for that.
This seems not to be the case.
Do I have to explicitly destroy the promise (what goo is a promise to timer that has been cancelled?).? If so, how & would I then have to explicitly set it to null
?
I think that I should use cancel(getOverviewMapTimer);
, but am not 100% sure as getOverviewMapTimer
is still non-null afterwards.
Thanks for your help
After var getOverviewMapTimer = $interval(...);
getOverviewMapTimer
holds a reference to an object (that happens to be a promise).
Doing $interval.cancel(getOverviewMapTimer)
passes (and cancels) the object referenced by the getOverviewMapTimer
variable, but there is no way to convert an object to null. The getOverviewMapTimer
variable will continue to hold a reference to the promise object and the only way to set it to null is through a new assignment (i.e. explicitely setting it to null):
var getOverviewMapTimer = $interval(...);
...
$interval.cancel(getOverviewMapTimer);
getOverviewMapTimer = null;
Advanced Topic:
It sounds indeed nice to have an easy way to find out if an interval-promise has been cancelled or not (e.g. adding a custom cancelled
property to the promise object and setting its value to true when cancelling the interval).
Angular is cool enough to be incredibly flexible and extensible, so using the concept of a Service Decorator we are able to "augment" the $interval
service, extending its cancel()
method to add a cancelled
property and setting its value to true
when cancelling an interval-promise:
/* Service Decorators can be configured in `config` blocks */
app.config(function ($provide) {
/* Register a decorator for the `$interval` service */
$provide.decorator('$interval', function ($delegate) {
/* Keep a reference to the original `cancel()` method */
var originalCancel = $delegate.cancel;
/* Define a new `cancel()` method */
$delegate.cancel = function (intervalPromise) {
/* First, call the original `cancel()` method */
var retValue = originalCancel(intervalPromise);
/* If the promise has been successfully cancelled,
* add a `cancelled` property (with value `true`) */
if (retValue && intervalPromise) {
intervalPromise.cancelled = true;
}
/* Return the value returned by the original method */
return retValue;
};
/* Return the original (but "augmented") service */
return $delegate;
});
});
Now, we can use the $interval
service as usual and we can always check an interval-promise's cancelled
property to find out if it has been cancelled.
var getOverviewMapTimer = $interval(...);
...
console.log(!!getOverviewMapTimer.cancelled); // false
$interval.cancel(getOverviewMapTimer);
console.log(!!getOverviewMapTimer.cancelled); // true
See, also, this short demo.
It's technically impossible that getOverviewMapTimer
is null
after calling $interval.cancel(getOverviewMapTimer);
.
If you want it to be null you have to do it yourself. Either immediately after cancelling the interval or via callback:
if ($interval.cancel(getOverviewMapTimer)) {
getOverviewMapTimer = null;
}
or
var getOverviewMapTimer = $interval($scope.UpdateOverviewMap, UPDATE_FREQUENCY);
getOverviewMapTimer.catch(function() { getOverviewMapTimer = null; });
Be aware, though, that the callback is asynchronous.
easy
var interval = $interval(function() { }, 1000);
console.log(interval.$$state.status); //0
$interval.cancel(interval);
console.log(interval.$$state.status); //2
if(interval.$$state.status == 0)
//valid
else
//invalid