简体   繁体   中英

Angular http post on loops

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM