1

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. e.g. If I have 4 items in the list of LifeBenefitTRAD, my post method is executing 4 times but w.r.t the fourth item in the list.enter image description here 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;
                }
            });
        });
       // }
    };
11
  • 1
    In order for us to help we need to know exactly what's happening, why it's wrong, and what you expect or want to happen. Commented Jan 29, 2015 at 21:01
  • 3
    Looks like you are updating the same scope variable.. ? But not sure what you want to do.. Commented Jan 29, 2015 at 21:02
  • Hi, I have edited my question..please let me know if it's still unclear. Commented Jan 29, 2015 at 21:06
  • I have already edited my question to make it clear then why is this negative vote ? Commented Jan 29, 2015 at 21:13
  • 1
    @Anilkumar I didn't downvote, but you're overwriting the same set of scope properties in every iteration. How is that supposed to work? Commented Jan 29, 2015 at 21:27

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

This seems working but not in the order the parameters are fed. Can we do anything so that post happens in the same order w.r.t the items in the loop?
How will it execute in FIFO order?
@Anilkumar The only easy solution involving $http that I can think of is to do the requests one at a time. Please see my edit.
1

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;
        });
    }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.