Rob Allsopp
Rob Allsopp

Reputation: 3518

Angular promise resolves inside function but not outside

I have a recursive function checking for some data every half second or so. The function returns a promise. Once I find the data, I want to resolve the promise and pass the data as the resolution. The problem is, the promise won't call .then() outside of the function. Here's the fiddle: http://jsfiddle.net/btyg1u0g/1/.

Here's the fiddle code:

Service:

myApp.factory('myService', function($q, $timeout) {

    var checkStartTime = false;
    var checkTimeout = 30000;

    function checkForContent() {

        var deferred = $q.defer();

        // simulating an $http request here
        $timeout(function () {

            console.log("Checking...");

            if (!checkStartTime) checkStartTime = new Date();

            // this would normally be 'if (data)'
            if ((new Date()) - checkStartTime > 3000) {
                deferred.resolve("Finished check");
                checkStartTime = false; // reset the timeout start time
            } else {
                // if we didn't find data, wait a bit and check again
                $timeout(function () {
                    checkForContent();
                }, 400);
            }

        }, 5);

        // then is called in here when we find data
        deferred.promise.then(function(message) {
             console.log("Resolved inside checkForContent");
        });

        return deferred.promise;

    }

    return {
        runCheck: function() {
            return checkForContent()
        }
    }
});

Controller:

myApp.controller('MyCtrl', function ($scope, myService) {
    $scope.name = 'Superhero';

    // then is never called
    myService.runCheck()
    .then(function (message) {
        console.log("Resolved outside checkForContent");
    });

});

Upvotes: 5

Views: 1196

Answers (1)

Mikke
Mikke

Reputation: 2167

Check out this fiddle.

The outter $timeout function is named so it can be called from within itself.

$timeout(function inner() {
  // ...

Then it is called recursively like this:

$timeout(function () {
  inner();
}, 400);

Upvotes: 1

Related Questions