Having trouble calculating the total sum within a for loop

I have a special function inside a loop that generates an array of objects. My goal is to calculate the total value returned by this function, but unfortunately I am not getting the correct sum. The function itself is working properly, however, I am unable to obtain the total sum. Below you can see the code snippet:

controller

var TotalOBValueLand = 0;
for(var i = 0; i < $scope.selectedProp.length; i++){
     AccountService.getTopAccountDetails($scope.selectedProp[i]["propId"]).then(function(msg){
           TotalOBValueLand += parseInt(msg.data[0].OBValueLand);
           //The data being returned shows no errors.
     });
}
console.log(TotalOBValueLand); //I always get zero;

Answer №1

Utilize Promise.all and array#map to retrieve an array of results, then employ Array#reduce to calculate the sum

var TotalOBValueLand = 0;
Promise.all($scope.selectedProp.map(function(prop) {
     return AccountService.getTopAccountDetails(prop).then(function(msg){
           return parseInt(msg.data[0].OBValueLand);
     });
})).then(function(results) {
    TotalOBValueLand = results.reduce(function(a, b) {
       return a + b; 
    });
    console.log(TotalOBValueLand);
});

Addressing the feedback received

var TotalOBValueLand = 0;
var TotalOBValueBuilding = 0;
Promise.all($scope.selectedProp.map(function(prop) {
     return AccountService.getTopAccountDetails(prop).then(function(msg){
           return parseInt(msg.data[0]);
     });
})).then(function(results) {
    TotalOBValueLand = results.reduce(function(a, b) {
       return a.OBValueLand + b.OBValueLand; 
    });
    TotalOBValueBuilding  = results.reduce(function(a, b) {
       return a.OBValueBuilding  + b.OBValueBuilding ; 
    });
    console.log(TotalOBValueLand, TotalOBValueBuilding);
});

Expanding on a more versatile solution

Promise.all($scope.selectedProp.map(function(prop) {
     return AccountService.getTopAccountDetails(prop).then(function(msg){
           return parseInt(msg.data[0]);
     });
})).then(function(results) {
    var totals = results.reduce(function(result, a) {
        Object.keys(a).forEach(function(key) {
            result[key] = (result[key] || 0) + a[key];
        });
        return result;
    }, {});
    console.log(totals.OBValueLand, totals.OBValueBuilding);
});

Answer №2

Trying to access console.log(TotalOBValueLand); outside of the response won't work as .getTopAccountDetails() is an asynchronous function, resulting in it always being at 0.

To solve this issue, you can enclose it within:

var TotalOBValueLand = 0;
for(var i = 0; i < $scope.selectedProp.length; i++){
     AccountService.getTopAccountDetails($scope.selectedProp[i]["propId"]).then(function(msg){
           TotalOBValueLand += parseInt(msg.data[0].OBValueLand);
           console.log(TotalOBValueLand);  
     });
}

Answer №3

One issue arises from the mixing of asynchronous and synchronous functions, leading to unexpected behavior. To better illustrate this concept, consider the following demonstration:

Demo Link

AccountService = {
  getTopAccountDetails: function() {
    return new Promise((resolve) => resolve(1))
  }
}

var TotalOBValueLand = 0;
for(var i = 0; i < 2; i++){
     AccountService.getTopAccountDetails().then(function(x){
       TotalOBValueLand += x;
       console.log('async increment', TotalOBValueLand)
     });
}
console.log('sync', TotalOBValueLand);
setTimeout(() => 
console.log('timeout', TotalOBValueLand), 2000)

A better solution involves utilizing an array of promises that can be resolved together:

var TotalOBValueLand = 0;
promises = []
for(var i = 0; i < 2; i++){
  promise = AccountService
    .getTopAccountDetails()
  promises.push(promise)
}
console.log('before', TotalOBValueLand);

Promise
  .all(promises)
  .then(results => {
    TotalOBValueLand = results.reduce((curr,acc) => curr + acc, 0);
    console.log('completed', TotalOBValueLand);
    return TotalOBValueLand;
  })
  .catch(err => 'handle me')

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The HTML elements in my JSX code seem to constantly shift around whenever I resize my webpage

Using react.js, I'm currently developing a website that appears like this before resizing: pre-resize_screenshot_website However, upon vertical or diagonal resizing, the layout becomes distorted especially in the 'availability search bar' ...

Seamlessly transition between various states within a React component for a fluid user experience

I'm currently working on a simple component structured like this: var component = React.createClass({ render: function(){ if (this.props.isCollapsed){ return this.renderCollapsed(); } return this.renderActive() }, ren ...

In VueJS, where specifically do you typically look to catch emitted events?

Let's set the stage: export default Vue.extend({ name: 'Home', computed: { ...mapState('user', ['card']), }, created() { this.fetchData(); }, mounted() { this.$once('dataLoaded', () => { if ...

When dalekjs attempted to follow a hyperlink with text in it, the link failed to function properly

My goal is to retrieve an element from a list by clicking on a link containing specific text. Here is the HTML code snippet: <table> <td> <tr><a href='...'>I need help</a></tr> <tr><a href=&a ...

The art of defining PropTypes for the style attribute in Reactjs

Is there a way to pass the 'style' attribute into my component using JSX syntax? <InputTextWithValidation id="name" style={{width:'100%'}} .../> I'm wondering how I should define the PropTypes for ...

Enable Class exclusively on upward scrolling on the browser

Is there a way to dynamically change the class of an element only when the user scrolls the browser page upwards? Issue Filide>> JavaScript $(window).scroll(function() { var scroll = $(window).scrollTop(); if (scroll <= 100) { ...

Jasmine tests for AngularJS directive failed to invoke the link function

I can't figure out why the link function of my directive isn't being called in a Jasmine test. I've created a simple example to illustrate. Here is the code for my directive (TestDirective.js): 'use strict'; angular.module(&ap ...

Arranging Functions in JavaScript

I am encountering an issue regarding the execution of JavaScript functions within HTML. Specifically, I am using dimple.js to create a graph and need to select an svg element once the graph is created via JavaScript. Despite placing my jQuery selector as t ...

ReactJS bug: Array rendering problem affected by recent changes

Why does ReactJS remove the first element instead of the middle element when using array.splice to remove an element from an array? This is my code. I am using Redux as well. const reducerNotesAndLogin = (state = initialState, action) => { var tableNo ...

The ion-input border seems to be fluctuating as the keyboard appears on the screen

I'm currently working with Ionic 3 and experiencing an issue where the selected ion-input's border in the ion-content is shifting when the device keyboard appears on the screen. Here is a visual representation of the problem: https://i.stack.imgu ...

Search timeout restriction

I have a function that makes a request to the server to retrieve data. Here is the code for it: export default class StatusChecker { constructor() { if (gon.search && gon.search.searched) { this.final_load(); } else { this.make_req ...

Sending angularjs form data to nodejs Express (Failure in request)

Recently, I started learning AngularJS and decided to create a simple login feature using AngularJS on the front end and Nodejs on the server side. Security is not a priority for me at the moment, as I am focused on understanding how to make HTTP posts. I ...

Using HTTPS, you can access Flask from AJAX

I have encountered numerous inquiries concerning this issue, but none have proven effective for me. I recently switched my domain from HTTP to HTTPS. Everything was functioning properly on HTTP. The main issue lies in the fact that my javascript and flask ...

Preventing Bidirectional Binding in AngularJS: A Step-by-Step Guide

I have a basic script using angular js <script> var delightApp = angular.module('delightmeter', []); delightApp.controller('delightController', function ($scope) { $scope.delightScore = 0; ...

Encountering the error "object object" while attempting to pass parameters to my servlet through AJAX

Experiencing an issue where my ajax call is ending up in the error function. I have noticed that my success function is empty, but I was expecting to receive messages from my servlet whether the data provided is correct or incorrect. The popup dialog displ ...

When the onClick event is triggered, my intention is to dynamically insert a new

I'm having trouble adding a new row on each click, as my code keeps replacing the existing row. I attempted moving the if statement outside the addTable function, but it didn't work as expected. I've tried multiple solutions without succes ...

Loop through the input template using ng-repeat with various data types

I have been working on developing a user interface for adding and modifying information in a database. To manage the database, I am utilizing breeze, displaying data using angular grid, and incorporating a ui-bootstrap modal dialog for user interaction. ...

Error in the Angular-UI calendar

I'm encountering an issue while trying to set up the angular-ui calendar. When I run it, I get the following error: TypeError: undefined is not a function at Object.eventsWatcher.onChanged (http://localhost/fisioGest/js/calendar.js:262:41) Despite b ...

both modules loading at the same time in AngularJS

var moduleA=angular.module("MyModuleX",[]); moduleA.controller("MyControllerX",function($scope){ $scope.name = "John X"; }); var moduleB=angular.module("MyModuleY",[]); moduleB.controller("MyControllerY", function($scope) { $scope.name = "Sarah Y" ...

Tips for optimizing the "framerate" (setInterval delay) in a JavaScript animation loop

When creating a JavaScript animation, it's common practice to use setInterval (or multiple setTimeouts) to create a loop. But what is the optimal delay to set in these setInterval/setTimeout calls? In the jQuery API page for the .animate() function, ...