Reputation: 4898
I was trying to chain some promises for this service I have but the $stateprovider resolves without waiting for $q. This results in my controller getting back the result object with just the empty array, and the object gets filled later on. Where is my promise chain going wrong?
.state('somestate', {
resolve: {
neededvalue: function(anotherservice) {
return anotherservice.getData(); //this one works pretty well , but doesn't use any chaining
},
finalvalue: function(myService, neededvalue) {
return myService.startChain(neededvalue);
}
}
}
app.factory("myService",
['$resource', '$q',
function ($resource, $q) {
var firstApi = $resource("api/somewhere/first", {}, { "getData": { method: "POST" } });
var secondApi = $resource("api/somewhere/second", {}, { "getData": { method: "POST" } });
var result = {
array: []
};
var myService = {
startChain: startChain
};
return myService;
function startChain(someNeededValues) {
var deferred = $q.defer();
firstApi
.getData(someNeededValues.values).$promise
.then(function (data) {
result.value = data.value;
})
.then(recurringAction)
.then(deferred.resolve(result));
return deferred.promise;
}
function recurringAction() {
return secondApi.getData(result.value, function (data) {
angular.copy(data.array, result.array);
}).$promise;
}
}]);
Upvotes: 1
Views: 425
Reputation: 168
not sure if your script worked the way you intended to when you passed deferred.resolve(result)
as a callback to promise...
so just change
.then(deferred.resolve(result));
to
.then(function(){
deferred.resolve(result)
});
Upvotes: 3
Reputation: 4898
Well, this was actually a stupid mistake on my behalf.
I needed to wrap the deferred.resolve
inside of a function.
function startChain(someNeededValues) {
var deferred = $q.defer();
firstApi
.getData(someNeededValues.values).$promise
.then(function (data) {
result.value = data.value;
})
.then(recurringAction)
.then(function () {
deferred.resolve(result);
});
return deferred.promise;
}
Seems like $defer auto resolves or something if there is no .resolve method available.
Upvotes: 1
Reputation: 136144
Its an expected behavior of ng-resource
promise
From Angular Doc directly
It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data. This means that in most cases one never has to write a callback function for the action methods.
Upvotes: 1