Almog Baku
Almog Baku

Reputation: 800

AngularJS | Create chained promise

I would like to create a chained promise for my service provider:

this.$get = function($q, $window, $rootScope) {
    var $facebook=$q.defer();

    $rootScope.$on("fb.load", function(e, FB) {
        $facebook.resolve(FB);
    });

    $facebook.api = function () {
        var args=arguments;
        args[args.length++] = function(response) {
            $facebook.resolve(response);
        };

        $facebook.promise.then(function(FB) {
            FB.api.apply(FB, args);
        });

        return $facebook.promise;
    };

    return $facebook;
};

Than I call to the promise: $scope.user=$facebook.api("/me");

The problem is that because the deferred was already resolved its not wait until the api method will resolve it..

How can I chain them in a way the last promise will wait until the last promise will resolved?

Upvotes: 1

Views: 1057

Answers (1)

urish
urish

Reputation: 9033

It seems like you need two separate promise objects: One for the fb.load event and another one for the result of the API call.

Try chaning your code to read -

this.$get = function($q, $window, $rootScope) {
    var apiLoaded=$q.defer();

    $rootScope.$on("fb.load", function(e, FB) {
        apiLoaded.resolve(FB);
    });
    // You should reject the promise if facebook load fails.

    $facebook.api = function () {
        var resultDefer = $q.defer(),
            args=arguments;

        args[args.length++] = function(response) {
            $rootScope.$apply(function() {
                resultDefer.resolve(response);
                // you should reject if the response is an error
            });
        };

        return apiLoaded.promise.then(function(FB) {
            FB.api.apply(FB, args);
            return resultDefer.promise;
        });
    };

    return $facebook;
};

Also note that whenever you call resolve() from non-angularish code, you will need to wrap it with $rootScope.$apply(), otherwise then promise 'then' handlers will not get executed. Good luck!

Upvotes: 3

Related Questions