Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");
    });

});
like image 685
Rob Allsopp Avatar asked Nov 10 '22 02:11

Rob Allsopp


1 Answers

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);
like image 193
Mikke Avatar answered Nov 15 '22 12:11

Mikke