Can anyone provide guidance on how to calculate the total sum of a JavaScript array within an asynchronous function?

Currently, I am working with Angularjs Protractor for end-to-end testing and faced an issue while trying to calculate the sum of values in a column. Although I am able to print out each value within the loop successfully, I am struggling to figure out how to add them all together. Whenever I attempt to return the total after the loop, it turns out to be undefined.

function getTotal() {
  ptor.findElements(protractor.By.className('col33')).then(function(promColCells) {
    var total;
    for (var i = 2; i < promColCells.length; i += 2) {
      promColCells[i].getText().then(function(promCellString) {
        total += parseFloat(promCellString);
      });
    }
    return total;
  });
};

Answer №1

The previous response (now removed) presented a good approach but with bulky and inaccurate promise code. Utilizing $q.all (equivalent to Promise.all in ES6-compliant promise implementations) is how we can effectively wait for an array of promises to finish:

function calculateTotal() {
    // this is where we continue
    return driver.findElements(webdriver.By.className('col33')).then(function(elements) {
        // waiting for all elements  
        return $q.all(elements.map(function(element){ return element.getText()}));
    }).then(function(elementTexts){
        return elementTexts.reduce(function(a,b){ return a + Number(b);},0);
    });
}

Alternatively, if you're not a fan of Array#reduce, you can sum using a for loop.

To use this function, it would look something like this:

calculateTotal().then(function(total){
    alert(total); // total value will be accessible here
});

Keep in mind, using an external promise library such as Bluebird allows you to write:

return Promise.cast(driver.findElements(webdriver.By.className('col33')))
    .map(function(element){ return element.getText(); })
    .reduce(function(a,b){ return a+Number(b); });

This results in a cleaner code structure.

Answer №2

Protractor comes with a built-in map function.

Here is a suggestion on how you can use it:

function calculateTotal() {
  // This is similar to using element.all(by.css('.col33')). It will return
  // a promise that resolves to an array of strings.
  return $$('.col33').map(function(cell) {
    return cell.getText();
  }).
  then(function(values) {
     // Values is an Array.<string>. Parse the integers and return the sum.
     var result = 0;
     values.forEach(function(val) {
       result += parseInt(val, 10);
     });
     return result;
  });
};

calculateTotal.then(function(total) {
});

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

Frustratingly Quiet S3 Upload Failures in Live Environment

Having trouble debugging a NextJS API that is functioning in development (via localhost) but encountering silent failures in production. The two console.log statements below are not producing any output, leading me to suspect that the textToSpeech call ma ...

How to Access Data Attribute in React TypeScript on Click Event

Recently, I encountered a situation with my React component where I have a button with a click handler that utilizes the data-* attribute. In the past, with regular React, extracting the value from the data-* attribute was straightforward. However, as I am ...

What does the curly braces {} signify in the JavaScript programming language

While delving into sample code, I came across a line that left me puzzled. var foo = {}; From my observations, it seems like this is being used as a type of array where the index is a string provided by the user instead of traditional numerical indexes. ...

Distinguishing div identifiers for jQuery displaying and concealing

Although I am not a coder, I am still learning and trying to improve my skills. I have multiple div elements listed by a MySQL query. I require a JavaScript code that can display the class="qform" div based on which button is clicked. If button-1 is clic ...

Can an Expression be incorporated into the ng-model Directive?

I am facing an issue with my loop: <div ng-repeat="measure in CompleteDataSetViewModel.TargetMeasures"> </div> Within this loop, I have an input field: <input ng-model="CompleteDataSetViewModel.AnnualRecord.Target[measure.Name]_Original" ...

Accessing a key from an object dynamically in a React list and resolving key error issues in React

I encountered two challenges: I am currently retrieving JSON data from APIs. [ { "title": "Basic Structures & Algoritums", "lesson_id": 3, "topics": { "Title": &q ...

Having difficulty uploading a file using a formGroup

Currently, I am using Angular to create a registration form that includes information such as name, email, password, and avatar. For the backend, I am utilizing NodeJS and MongoDB to store this information. I have successfully written the registration API ...

Switching back and forth between fluid text fields

Is there a way to navigate between dynamically generated textfields using an iterator from struts-tags? <s:iterator value="aList"> <td width="50px" align="center"> <s:textfield name="solField" size="2" maxlength="1" style="text-transform ...

Angular project icons not displaying in the browser

My current project in Angular was functioning properly until recently. I am facing an issue where the images are not being displayed on the browser when I run ng serve, resulting in a 404 error. Interestingly, everything else seems to be working fine witho ...

Ways to Export HTML to Document without any borders or colorful text

How can I make a contentEditable area visible when filling text and then disappear when exporting the document? I found a script online that allows you to do this, but the issue is that the contentEditable area is not visible until clicked on. To address t ...

Parsing an Object in Java

I have a JavaScript object that I am sending back to Java using AJAX: var jsonData = { "testJson" : "abc", "userId" : "123" }; After printing the map, it appears as follows: key: jsondata value:[object Object] What is the correct ...

Converting CSS code into JavaScript

I am currently working with the following code: .mr15 > * margin-right: 15px &:last-child margin-right: 0 I need help translating this code to Javascript. Should I use JQuery or pure Javascript for this scenario? Thank you. ...

What is the best method for installing a package specified as a peerDependency?

I'm in the process of creating a library and I'm looking to figure out how to specify and install a dependency under peerDependencies. I couldn't find any information about this in the npm documentation when using the command npm install: ...

Update View Not Reflecting React State Increment

Here is the code snippet I am currently working with: class PickColor extends React.Component { constructor(props) { super(props); this.state = { active: 0 } this.setState = this.setState.bind(this); } ...

Modifying worldwide variables within an ajax request

After spending considerable time attempting to achieve the desired outcome, I am faced with a challenge. My goal is to append the object from the initial ajax call after the second ajax call. However, it appears that the for loop is altering the value to ...

Is it possible to use regex to replace all content between two dashes, including any new

I have a specific set of dashed markers that I am looking to update based on the content of $("#AddInfo"). If the field is not empty, I want to replace everything between the markers. Conversely, if $("#AddInfo") is empty, I need to remove all text betwe ...

What is the best way to use jQuery to set the height of one div equal to another div

Edited: I am facing a situation with a 3-column layout - Column A, Column B, Column C. The height of Column A is dynamic and I need to set the same height for both Column B and C. For instance, Column A contains a tabbed panel with varying heights based ...

Storing and Retrieving Multiple Data with localStorage

I need assistance with modifying my code. I have an input field labeled "mail" and I am trying to store email addresses and corresponding IDs in local storage. The email address should be taken from the "mail" input field while the ID should increment each ...

Restrict HTML Content in Json Result using PHP and Jquery

I'm currently working with a Controller that outputs JSON response and a JavaScript function that appends that response to the last tr in an HTML table. <pre> $reponse="<tr class=\"border_bottom\"><td>My Repo ...

Using Vue to dynamically upload multiple files simultaneously

Although this question has been asked frequently, most of the answers do not address a key issue - how to upload multiple images while knowing which image belongs to which data. Attempting to bind v-model to input file doesn't work as expected, and ev ...