Reputation: 800
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
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