Search code examples
angularjsintervalsangularjs-service

Confusion about how the promise returned by $interval works compared to $timeout in Angular


I'm having an issue understanding how the promise returned by $interval works in Angular.

Let's say in the following example, we have a simple "api" factory with a method called "getStuff" that returns an array with one item. We also have a controller that calls $timeout on that factory:

angular.module("app",[])
  .factory('api', function(){
    return {
      getStuff: function() {      
        return ["stuff"];
      } 
    };   
  })
  .controller('appCtrl', function($scope, $timeout, api){
    $timeout(api.getStuff, 1000)
      .then(function(response){
        console.log(response);
      });
  })

This will log '["stuff"]' in the console after 1 second, which is great.

So lets say I want to call that method every second by replacing $timeout with $interval. Now nothing happens:

angular.module("app",[])
  .factory('api', function(){
    return {
      getStuff: function() {      
        return ["stuff"];
      } 
    };   
  })
  .controller('appCtrl', function($scope, $interval, api){
    $interval(api.getStuff, 1000)
      .then(function(response){
        console.log(response);
      });
  })

What is different between $timeout and $interval in this case?

I appreciate all help!


Solution

  • The only thing you can do with the promise returned by $interval is cancel it (to stop its execution):

    var handle = $interval(someFunc, 1000);
    ...
    $interval.cancel(handle);
    

    Your code should probably look like:

    app.controller('appCtrl', function($scope, $interval, api) {
        $interval(function() {
            console.log(api.getStuff());
        }, 1000);
    });
    

    To be fancy and see everything working together:

    app.controller('appCtrl', function($scope, $interval, $timeout, api) {
        var handle = $interval(function() {
            console.log(api.getStuff());
        }, 1000);
    
        $timeout(function() {
            $interval.cancel(handle);
        }, 5000);
    });