anges244
anges244

Reputation: 697

AngularJS $interval function continues after route change

I have a function inside a controller which is based on setInterval. I noticed that after first calling it, it worked fine but continued even after the route changed. Afterwards i tried using the native $interval service which would automatically track changes in scope. The problem however remains. So now i have two questions. The first one is what can i do so that i use a repeated function inside a specific controller that stops when the user leaves that route? Also why does the scope function continue since i've changed scopes?

UPDATE - Code is like this

$scope.refreshScore() {
        ....
      }
$scope.refreshMe = function(){
  $interval($scope.refreshScore, 10000);
}

Upvotes: 26

Views: 16087

Answers (3)

Matt
Matt

Reputation: 35203

Try this:

    $scope.refreshScore = function() {
       // your logic here
    }
    var promise = $interval($scope.refreshScore, 10000);
    $scope.$on('$destroy',function(){
        if(promise)
            $interval.cancel(promise);   
    });

It will destroy the interval when you change the route.

Upvotes: 12

calebboyd
calebboyd

Reputation: 5753

Maybe try canceling it on the destroy event of the scope.

$scope.refreshScore() {
   ....
}
var intervalPromise;
$scope.refreshMe = function(){
    intervalPromise = $interval($scope.refreshScore, 10000);
}
$scope.$on('$destroy',function(){
    if(intervalPromise)
        $interval.cancel(promiseFromInterval);   
});

$interval may not be the best solution for this, especially if it is some async operation. If you absolutely have to have some timed operation that you want to occur preciously every x ms I would use something like this:

var refreshingPromise; 
var isRefreshing = false;
$scope.startRefreshing = function(){
   if(isRefreshing) return;
   isRefreshing = true;
   (function refreshEvery(){
         //Do refresh
         //If async in then in callback do...
         refreshingPromise = $timeout(refreshEvery,10000)
    }());
} 

Then do the same thing as above

If you're having trouble canceling the refresh you might try subscribing to some sort of route change event. And doing it there.

Upvotes: 40

John
John

Reputation: 21

For one simple solution, you can just use $location.$$path before you fire the event associated with the interval.

If the path does not correlate with the ui, don't fire it and cancel it.

Upvotes: 2

Related Questions