Angular Poller

by Warspawn

HTML

<div ng-app="Demo" ng-controller="DemoCtrl">
    <span>Val: {{ val }}</span>
    <button ng-click="startit()">Start</button>
    <button ng-click="stopit()">Stop</button>
    <button ng-click="restartit()">Restart</button>
    <button ng-click="clearit()">Clear</button>
    <div>
        {{ notify }} <br>
        {{ poller.polls() }}
    </div>
</div>

JavaScript

angular.module('Demo', [])
.service('Poller', ['$http', '$q', '$timeout', '$log', function($http, $q, $timeout, $log) {
    var polls = {};
    
    var doPoll = function(name, method, interval) {        
         return $timeout(method, interval);
    };
    
    var chainPoll = function(promise, name, method, interval) {
                promise.then(function(update) { 
                    $log.log('timeout resolved: ', update);
                    
                    if(!polls[name]) {
                        $log.error('poll already deleted');
                        return;
                    }
                    if(polls[name] && polls[name].status === 'polling') {
                        polls[name].poll = doPoll(name, method, interval);
                        polls[name].deferred.notify(update);
                    } else {
                       polls[name].status = 'cancelled';
                       $timeout.cancel(polls[name].poll);
                        return polls[name].deferred.resolve(update);
                    }
                }, function() {
                    $log.log('promise reject');
                    if(polls[name] && polls[name].deferred) {
                        return polls[name].deferred.reject('timeout rejected');
                    }
                });   
    };
    
    this.start = function(name, method, interval) {
        var deferred = $q.defer();
        
        if(polls[name]) {
            return polls[name].deferred.promise;
        } else {
            polls[name] = {};
            polls[name].method = method;
            polls[name].interval = interval;
            polls[name].deferred = deferred;
            polls[name].status = 'polling';
           
            polls[name].poll = doPoll(name, method, interval);
            
            chainPoll(polls[name].poll, name, method, interval);
            
            return polls[name].deferred.promise;
        }
    };
    
    this.stop = function(name) {
  ...