I am trying to use angular http post inside a loop using angular forEach as advised here- Angular HTTP Get on loop and Angularjs loop trought $http.post but the solution is not working in my case. The http post always returns result with respect to the last item in LifeBenefitTRAD but I want the result for each item in the loop. eg If I have 4 items in the list of LifeBenefitTRAD, my post method is executing 4 times but wrt the fourth item in the list. The execution always happens with respect to last object.Please tell me what am I doing wrong here?-
$scope.GenerateAllTradQuote = function () {
var TRADPlanDetails = {};
console.log(LifeBenefitTRAD);
//for (var i = 0; i < LifeBenefitTRAD.length; i++) {
LifeBenefitTRAD.forEach(function (trad) {
TRADPlanDetails.QuoteName = "TradQuote_" + trad.LifeBenefitValue;
TRADPlanDetails.LifeBenefitId = trad.LifeBenefitId;
TRADPlanDetails.LifeBenefitValue = trad.LifeBenefitValue;
console.log(TRADPlanDetails);
$http({
url: key_Url_GenerateTradQuote,
method: key_String_HttpPost,
// async: true,
params: TRADPlanDetails
}).then(function (result) {
$scope.TRAD_PlanDetails.TRAD_DisplayFlag = true;
if (result.data != key_String_Zero) {
$scope.TRAD_PlanDetails.TRAD_DisplayMsg = key_Confirm_Successful_Quote;
}
else {
$scope.TRAD_PlanDetails.TRAD_DisplayMsg = key_Confirm_failed_Quote;
}
});
});
// }
};
You are declaring the TRADPlanDetails
variable outside of the forEach
callback, which means that you are passing the same object to $http
every time. If there is some delay before $http
actually uses your values, then it will wind up using the same set of values for all of its requests.
Please try creating a new variable and a new object each time:
LifeBenefitTRAD.forEach(function (trad) {
var planDetails = {
QuoteName: "TradQuote_" + trad.LifeBenefitValue,
LifeBenefitId: trad.LifeBenefitId,
LifeBenefitValue: trad.LifeBenefitValue
};
$http({
url: key_Url_GenerateTradQuote,
method: key_String_HttpPost,
// async: true,
params: planDetails
})
// ....
});
If maintaining the order of the original requests is important, you can do the following, but be aware that it will slow the process down because it will essentially wait for each request to finish before beginning the next one:
LifeBenefitTRAD.reduce(function (p) {
var planDetails = {
QuoteName: "TradQuote_" + trad.LifeBenefitValue,
LifeBenefitId: trad.LifeBenefitId,
LifeBenefitValue: trad.LifeBenefitValue
};
return p.then(function () {
return $http({
url: key_Url_GenerateTradQuote,
method: key_String_HttpPost,
// async: true,
params: planDetails
});
})
.then(function (result) {
// handle result for current request
});
}, $q.when());
The above requires using the $q
service.
There may be a way to do some low-level stuff with $http
that would allow you to initiate a new request right as the previous one was about to be sent off, but from what I can see, it doesn't provide anything that would easily facilitate that.
JLRishe's answer is part of it, but you also want to store the results differently, so you might want to consider doing something like this:
$scope.GenerateAllTradQuote = function () {
// Clear out existing details
$scope.TRAD_PlanDetails = {};
// This is more compatible than Array.forEach()
angular.forEach(LifeBenefitTRAD, function (trad) {
var planDetails = {
QuoteName: "TradQuote_" + trad.LifeBenefitValue,
LifeBenefitId: trad.LifeBenefitId,
LifeBenefitValue: trad.LifeBenefitValue
};
$http({
url: key_Url_GenerateTradQuote,
method: key_String_HttpPost,
params: TRADPlanDetails
}).then(function (result) {
planDetails.TRAD_DisplayFlag = true;
if (result.data != key_String_Zero) {
planDetails.TRAD_DisplayMsg = key_Confirm_Successful_Quote;
} else {
planDetails.TRAD_DisplayMsg = key_Confirm_failed_Quote;
}
$scope.TRAD_PlanDetails[planDetails.QuoteName] = planDetails;
});
});
};
You could alternatively use an array to store it and just push the completed planDetails
object to it; up to you.
If you wanted to retain the order of request, you could store the LifeBenefitTRAD loop's index:
$scope.GenerateAllTradQuote = function () {
// Clear out existing details
$scope.TRAD_PlanDetails = {};
// This is more compatible than Array.forEach()
angular.forEach(LifeBenefitTRAD, function (trad, idx) {
var planDetails = {
QuoteName: "TradQuote_" + trad.LifeBenefitValue,
LifeBenefitId: trad.LifeBenefitId,
LifeBenefitValue: trad.LifeBenefitValue
};
$http({
url: key_Url_GenerateTradQuote,
method: key_String_HttpPost,
params: TRADPlanDetails
}).then(function (result) {
planDetails.TRAD_DisplayFlag = true;
planDetails._index = idx;
if (result.data != key_String_Zero) {
planDetails.TRAD_DisplayMsg = key_Confirm_Successful_Quote;
} else {
planDetails.TRAD_DisplayMsg = key_Confirm_failed_Quote;
}
$scope.TRAD_PlanDetails[planDetails.QuoteName] = planDetails;
});
});
};
...Aaaaaand if you needed to put them into the $scope
in an array, in order, you could do something like this:
$scope.GenerateAllTradQuote = function () {
// Clear out existing details
var TRAD_PlanDetails = [];
// This is more compatible than Array.forEach()
angular.forEach(LifeBenefitTRAD, function (trad, idx) {
var planDetails = {
QuoteName: "TradQuote_" + trad.LifeBenefitValue,
LifeBenefitId: trad.LifeBenefitId,
LifeBenefitValue: trad.LifeBenefitValue
};
$http({
url: key_Url_GenerateTradQuote,
method: key_String_HttpPost,
params: TRADPlanDetails
}).then(function (result) {
planDetails.TRAD_DisplayFlag = true;
planDetails._index = idx;
if (result.data != key_String_Zero) {
planDetails.TRAD_DisplayMsg = key_Confirm_Successful_Quote;
} else {
planDetails.TRAD_DisplayMsg = key_Confirm_failed_Quote;
}
TRAD_PlanDetails.push(planDetails);
// If at the last entry:
if (idx >= LifeBenefitTRAD.length - 1) putOnScope();
});
});
function putOnScope() {
$scope.TRAD_PlanDetails = TRAD_PlanDetails.sort(function(a, b) {
return a._index - b._index;
});
}
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.