55

I am using the Javascript command: setInterval. I like to stop it when the user leaves the page.

This code seems to work well: http://jsfiddle.net/PQz5k/

It detects when a user leaves a page. It executes Javascript code when a user clicks on a link to go to a different HTML page or URL, or if user reloads page.

However, it does not work when I go from one AngularJS template to another. As an example, if I am at template1.html, I want the Javascript code to do something in Controller1.js when the user leaves template1.html to go to template2.html. What is the equivalent of this code below in AngularJS?:

$(window).on('beforeunload', function() { return 'Your own message goes here...'; });​ 
1
  • Are you actually switching full pages at the html root or are you switching templates in an ng-view? Commented Dec 17, 2012 at 5:14

4 Answers 4

142

I think you have two controllers, one for each template like this:

function Controller_1($scope...){ ... } function Controller_2($scope...){ ... } 

Well, when you switch from one template to another there's an event that's fired called $destroy, you can read up on it here http://docs.angularjs.org/api/ng.$rootScope.Scope#$destroy

Let's say I'm switching from the template with Controller_1 to the template with Controller_2. Controller_1 has an interval I'd like to stop. You can accomplish this with:

function Controller_1($scope, $interval...){ var myInterval = $interval(...); $scope.$on("$destroy", function(){ $interval.cancel(myInterval); }); } 

This will mean that when the $scope for Controller_1 is destroyed, the event will be called and the interval will be cleared.

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

5 Comments

@Matthew Berg: Thanks for your help! That worked. However, I now have another problem. I have multiple functions in my Controller1, which are executed by different buttons/links on Template1. When I click on those links, the SetInterval is still running. I've even put ClearInterval(myInterval) in the function that calls SetInterval, but it still does not stop the SetInterval.
I think I found the other part of the solution at stackoverflow.com/questions/8476045/how-to-stop-setinterval I have to clear the myInterval variable at the top of the Controller so that it is exposed to all of my functions.
$scope.$on('$destroy') works but you should use $interval.cancel(myInterval); to keep with the angular way.
You have to destroy the interval when the scope is destroyed, so $interval.cancel will not help you. I.e. you have a view with a controller that continuously needs to run an interval and only when you leave the view do you want the interval to stop.
Awesome tip! That makes such a nice clean way to handle setInterval ids. Thanks!
12

This is for when you leave a template (also prompt a confirm dialog):

 function Controller_1($scope...){ var myInterval = setInterval(...); $scope.$on('$locationChangeStart', function (event, next, current) { console.log(current); if (current.match("\/yourCurrentRoute")) { var answer = confirm("Are you sure you want to leave this page?"); if (!answer) { event.preventDefault(); }else{ clearInterval(myInterval); } } }); } 

Comments

7

if you are using ui-router then you can use the onExit, property

 $stateProvider.state('foo', { url: '/foo', templateUrl: 'views/foo.html', controller: 'fooController', onExit: ['$fooService', function($fooService) => { $fooService.hide();//do what u want to do here }] }); 

Comments

0

You can use a watcher to check when the location path is changed, something like this:

$scope.$watch(function(){ return $location.path(); }, function(newPath, oldPath){ //...Do something }) 

Then, you can get the old location, and the new location and execute a function or whatever you want,

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.