Reputation: 6684
I have these ngResource queries in my controller:
Ages.query(function(ages){
$scope.ages = ages;
});
Skinissues.query(function(skinissues){
$scope.skinissues = skinissues;
});
Skintypes.query(function(skintypes){
$scope.skintypes = skintypes;
});
Activities.query(function(activities){
$scope.activities = activities;
});
In the same controller in findOne function:
$scope.findOne = function() {
Products.get({
productId: $routeParams.productId
}, function(product) {
for (var i = 0; i < product.ages.length; i ++){
for (var j = 0; j < $scope.ages.length; j ++){
if (product.ages[i].id == $scope.ages[j].id){
$scope.ages[j]['ticked'] = true;
}
}
}
for (var i = 0; i < product.activities.length; i ++){
for (var j = 0; j < $scope.activities.length; j ++){
if (product.activities[i].id == $scope.activities[j].id){
$scope.activities[i]['ticked'] = true;
}
}
}
for (var i = 0; i < product.skintypes.length; i ++){
for (var j = 0; j < $scope.skintypes.length; j ++){
if (product.skintypes[i].id == $scope.skintypes[j].id){
$scope.skintypes[i]['ticked'] = true;
}
}
}
for (var i = 0; i < product.skinissues.length; i ++){
for (var j = 0; j < $scope.skinissues.length; j ++){
if (product.skinissues[i].id == $scope.skinissues[j].id){
$scope.skinissues[i]['ticked'] = true;
}
}
}
for (var i = 0; i < $scope.parents.length; i ++){
if ($scope.parents[i].id == product.parent.id){
$scope.parents[i]['ticked'] = true;
}
}
console.log('Products', product);
$scope.product = product;
});
};
This code, sometimes, it works, sometimes it doesn't, because in the findOne function, sometimes, the $scope.ages
$scope.skinissues
$scope.skintypes
or $scope.activities
is undefined.
This happens because their queries haven't finished yet.
What can I do to solve this problem?
Please help. Thanks.
Upvotes: 1
Views: 883
Reputation: 48968
Use $q.all
to resolve the $resource
promises.
angular.module('mean.variables')
.factory('Variables', function($q, Products, Ages, Activities, Skinissues, Skintypes, _){
return {
get: function(){
var promiseHash = {};
promiseHash.ages = Ages.query().$promise;
promiseHash.skinissues = Skinissues.query().$promise;
promiseHash.skintypes = Skintypes.query().$promise;
promiseHash.activities = Activities.query().$promise;
promiseHash.parents = Products.query().$promise;
return $q.all(promiseHash);
}
}
});
The above example function returns a promise that either resolves sucessfully to a hash of the query objects or resolves rejected with the first rejected response object.
The advantage of using $q.all()
instead of $q.defer
is that the promise chains aren't broken and error responses are retained for clients of the factory.
From the Docs:
The Resource instances and collections have these additional properties:
$promise
: the promise of the original server interaction that created this instance or collection.On success, the promise is resolved with the same resource instance or collection object, updated with data from server. This makes it easy to use in resolve section of
$routeProvider.when()
to defer view rendering until the resource(s) are loaded.On failure, the promise is rejected with the http response object, without the
resource
property.If an interceptor object was provided, the promise will instead be resolved with the value returned by the interceptor.
--AngularJS ngResource API Reference
all(promises);
Combines multiple promises into a single promise that is resolved when all of the input promises are resolved.
Parameters
An array or hash of promises.
Returns
Returns a single promise that will be resolved with an array/hash of values, each value corresponding to the promise at the same index/key in the promises array/hash. If any of the promises is resolved with a rejection, this resulting promise will be rejected with the same rejection value.
--AngularJS $q Service API Reference -- $q.all
Upvotes: 2
Reputation: 6684
Thanks guy, I've came up with this service by using setInterval to check if all variable are defined.
angular.module('mean.variables')
.factory('Variables', ['$q', 'Products', 'Ages', 'Activities', 'Skinissues', 'Skintypes', '_', function($q, Products, Ages, Activities, Skinissues, Skintypes, _){
return {
get: function(){
var variables = {};
var defer = $q.defer();
Ages.query(function(res){
variables.ages = res;
});
Skinissues.query(function(res){
variables.skinissues = res;
});
Skintypes.query(function(res){
variables.skintypes = res;
});
Activities.query(function(res){
variables.activities = res;
});
Products.query(function(res){
variables.parents = res;
});
var timer = setInterval(function(){
if (variables.ages && variables.activities && variables.skinissues && variables.skintypes && variables.parents){
defer.resolve(variables);
clearInterval(timer);
}
}, 50);
return defer.promise;
}
}
}])
Upvotes: 0