angularjsangularjs-directiveangular-broadcast

How to stop intervals inside Timeout delay on Event Broadcasts?


In my Angular 1.5, after user logs into their account, I have various directives that starts their interval inside a timeout. For example, I have this UserEmailNotificationsCtrl in one of the directives to check for new emails:

var intervalPromise;

$timeout(function () {
  stopInterval();
  intervalPromise = $interval(function() {
       checkNewEmail();
  }, 30000);
}, 20000);

$scope.$on('event:stop-intervals', function() {
      stopInterval();
});

$scope.$on('$destroy', function() {
   stopInterval();
});

function stopInterval() {
  $interval.cancel(intervalPromise);
}

If incase the user logsout, I broadcast an event so the above interval is stopped in order to prevent 400 Bad Requests:

function logout() {
 $rootScope.$broadcast('event:stop-intervals');
}

The above works fine. However, this is the problem I am having:

If incase, the user logs out before the interval checks gets started, as it is wrapped inside a timeout to start after 20 seconds, the event:stop-intervals broadcast is missed. In these cases, the interval starts after the set timeout and does not know that the event:stop-intervals was fired to stop intervals before this.

My question is: How can I check if the event:stop-intervals broadcast was fired before starting the interval in the directives? (or) How can the directive stop the interval from starting if event:stop-intervals was fired even before the interval check with timeout was triggered?


Solution

  • Cancelling $timeout promise using $timeout.cancel() in your stopInterval() method will fix your issue so the intervals will not be even set:

    var intervalPromise;
    
    var tiemoutPromise = $timeout(function () {
      stopInterval();
      intervalPromise = $interval(function() {
           checkNewEmail();
      }, 30000);
    }, 20000);
    
    $scope.$on('event:stop-intervals', function() {
      stopInterval();
    });
    
    $scope.$on('$destroy', function() {
      stopInterval();
    });
    
    function stopInterval() {
      $timeout.cancel(tiemoutPromise);
      $interval.cancel(intervalPromise);
    }