Reputation: 171
I have a function like this inside an angularJS app
function Validate() {
var inputs = $scope.getInput;
var defer = $q.defer();
var promises = [];
_.each(inputs, function(input) {
promises.push(loadInformation(input)
.then(function(inputList) {
repository.calculation(inputList, input);
if (inputList) {
return true;
}
else {
return false;
}
}));
});
$q.all(promises).then(function() {
for (var i = 0; i < promises.length; i++) {
if (!promises[i]) {
defer.reject();
}
}
defer.resolve(); // after it loops get the answer
});
return defer.promise;
}
function handleAction(event) {
if (Validate().value) {
alert('show success');
}
else {
alert('show failue');
}
alert('this is being hit before callback finishes');
}
I start the execution in handleAction(event) and it starts the Validate() async function. It goes through it and does nothing basically, then it executes the rest of handleAction(event) and it gives the alert
'this is being hit before callback finishes'
then before it reaches the end of the function it goes back to the async call and finishes executing.
2 questions:
Am I doing promises correct?
Also how do I make the alert('show success') or alert('show failure') to wait until the call is completely done and returns a result?
Upvotes: 0
Views: 54
Reputation: 28750
You just have to change your handleAction to use the promise instead:
function Validate() {
var inputs = $scope.getInput;
var promises = [];
_.each(inputs, function (input) {
promises.push(loadInformation(input)
.then(function (inputList) {
repository.calculation(inputList, input);
if (inputList) {
return true;
} else {
return false;
}
}));
});
return $q.all(promises)
.then(function (results) {
for(var x = 0; x < results.length; x++){
if(!results[x]){
return $q.reject("Rejected");
}
};
return "Resolved";
});
}
function handleAction(event) {
var validatePromise = Validate();
validatePromise.then(function(data){
//data === "Resolved"
}, function(error){
//error === "Rejected"
});
}
A few other things of note, once you've done something to a promise (reject/resolve) you shouldn't do one of those again so I modified that to do a return. Also you can pass in data to both resolve/reject. In the example I just pass in a string. Also instead of creating a defer you can just return the $q.all. At the same time checking if !promise[i] won't work as that's actually set. You have to check the result which I showed how to above.
Upvotes: 1