1

Inside of an angular controller I'm trying to stop an interval. Is it not possible to stop the interval if there is a .then promise chained to it?

Why does the stopCount function work here

var stop = $interval(function(){
    console.log('testing interval');
  }, 1000);

$scope.stopCount = function(){
  $interval.cancel(stop);
}

but not here with the .then

var stop = $interval(function(){
    console.log('testing interval');
  }, 1000)
  .then(function(){
     console.log('complete')
  });

$scope.stopCount = function(){
  $interval.cancel(stop);
}

Thanks in advance!

mattc19
  • 678
  • 1
  • 11
  • 23
  • Check this out http://stackoverflow.com/questions/25100585/confusion-about-how-the-promise-returned-by-interval-works-compared-to-timeout – Dustin Stiles Feb 17 '16 at 01:30
  • $timeout will return a promise that you can call .then on, because in a sense it is like a promise. It does something after a certain amount of time. Although interval is different, it just keeps going. So the ONLY thing you can do once you start it, is stop it – Dustin Stiles Feb 17 '16 at 01:31
  • If you would like to execute the console.log after 1 second, then just plug in $timeout instead of $interval and all should work :) – Dustin Stiles Feb 17 '16 at 01:31
  • Thanks for the explanation! So there is not a way to run a function after the interval has been canceled? – mattc19 Feb 17 '16 at 01:40
  • Think about this. the .then method returns a NEW promise. So you are trying to stop the NEW proimse, not the original One. – Dustin Stiles Feb 17 '16 at 01:42
  • Don't call then directly after the $interval. Instead, call it on the stop variable after the interval has been set – Dustin Stiles Feb 17 '16 at 01:43
  • Then your promise should work and you should get the default behaviour. The .then should be called on EACH completed cycle of the interval, as it is notified when the interval restarts. And since 'stop' is referencing the promsise that $interval returned, you should be able to stop it :) – Dustin Stiles Feb 17 '16 at 01:44
  • EDIT: Skipped all the comments and just submitted an answer. Let me know how it works! – Dustin Stiles Feb 17 '16 at 01:47

2 Answers2

1

Ok so you obviously dont completely understand about promises... The reason this dosent work:

var stop = $interval(function(){
    console.log('testing interval');
  }, 1000)
  .then(function(){
     console.log('complete')
  });

$scope.stopCount = function(){
  $interval.cancel(stop);
}

Is because you have two promises... The first one is the milliseconds which is 1000/ 1second. And the other one is a .then() promise. You cant use two promises in one function.

If you see the docs here You see that the syntax for $interval is:

$interval(fn, delay, [count], [invokeApply], [Pass]);

And for the cancel function this is the syntax

$interval.cancel([promise]);
amanuel2
  • 4,508
  • 4
  • 36
  • 67
  • How is $interval a promise of milliseconds? You can only cancel it. On a different note you can ABSOLUTELY use multiple callbacks on the same promise. Unless I misunderstood what you meant? – Dustin Stiles Feb 17 '16 at 01:34
  • Im not talking about multiple callbacks on the same promise. I said Multiple promises. @DustinStiles – amanuel2 Feb 17 '16 at 01:35
  • That part is totally true. I still don't understand the bit about there being two promises. $interval returns a promise, which is the only promise in the code. $interval returns a promise (.then) and that is it? Is there something I'm not seeing? – Dustin Stiles Feb 17 '16 at 01:39
  • I think I understand what you are saying, writing my own answer cleared it up :) – Dustin Stiles Feb 17 '16 at 01:48
  • Although the bit about using two promises IN one function is very confusing. It's true, but not what's happening with the OP's code. I think what you meant to say was, you can't store two promises in the same variable :) – Dustin Stiles Feb 17 '16 at 01:49
1

Try this!

// The problem is that stop is not storing the promise of $interval
// It's storing the promise returned by the .then method
var stop = $interval(function(){
  console.log('testing interval');
}, 1000)
.then(function(){
  console.log('complete')
});

$scope.stopCount = function(){
  $interval.cancel(stop);
}


// Try this
// Now stop is using $intervals promise,
// not .then. We'll call .then separately below
var stop = $interval(function(){
  console.log('testing interval');
}, 1000);

// Now we can cancel the 'stop' interval below
// This promise has to have a success callback
// AND an error callback.
stop.then(function(){
  console.log('complete')
}, function(err) {
  console.log('Uh oh, error!', err);
});

$scope.stopCount = function(){
  $interval.cancel(stop);
}
Dustin Stiles
  • 1,414
  • 9
  • 12