AngularJS - Polling w/ Promise

by gavinfoley

HTML

<div data-ng-app="myApp">
    <div data-ng-controller="MyCtrl"> 
        <span data-ng-bind="notify"></span> 
    </div>
</div>

CSS

</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> 
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script> 
<style>

JavaScript

// Load Google Maps after 4 seconds
(function () {    
    setTimeout(function () {
        var s = document.createElement("script");
        s.type = "text/javascript";
        s.src = "http://maps.google.com/maps/api/js?v=3&sensor=false";
        document.getElementsByTagName("head")[0].appendChild(s); 
    }, 4000);
}());


//Include angular-ui dependency in resources on the side and as 'ui'
angular.module('myApp', [])

.controller("MyCtrl", function ($scope, $timeout, $interval, $window, utils) {
    $scope.notify = "Waiting for Google...";    
    
    // Poll the global window for google 
    utils.poll(function () {
        return $window.google;
    }).then(function () { // then update our notification
        $scope.notify = "Google is ready";        
    });

})

.factory('utils', ['$timeout', '$q', function ($timeout, $q) {
    return {
        // Polls to check when a variable is defined.
        poll: function (whenReady, interval, timeout) {
            var deferred = $q.defer(),
            interval = parseInt(arguments[1], 10) || 50, // default to 50 milliseconds
            timeout = parseInt(arguments[2], 10) || Infinity; // default: poll until found
                
            (function poll() {
              var me = this;
                if (whenReady.apply(me)) {
                    deferred.resolve();
                } else if ((timeout -= interval) > 0) {
                    $timeout(poll, interval);
                }
            }());
            
            return deferred.promise;
        }
    };
}]);