I'm using Angularjs Protractor for e2e tesing, and I'm trying the sum the values in a column. Inside the loop I can print out each value fine, but I can't figure out how to add them all. If I try to return total after the for loop, it's 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;
});
};
I'm using Angularjs Protractor for e2e tesing, and I'm trying the sum the values in a column. Inside the loop I can print out each value fine, but I can't figure out how to add them all. If I try to return total after the for loop, it's 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;
});
};
Share
edited Dec 25, 2014 at 11:31
Benjamin Gruenbaum
277k89 gold badges520 silver badges517 bronze badges
asked Apr 7, 2014 at 17:15
BrendanBrendan
1,4714 gold badges18 silver badges37 bronze badges
3
- Are these operations async? If they are, you simply can't synchronously return the total from a series of async operations? If the operations aren't async, then I'm trying to figure out why you're even trying to use promises as there must be a simpler way. – jfriend00 Commented Apr 7, 2014 at 17:22
- The operations are async, that's what I'm mostly confused about. – Brendan Commented Apr 7, 2014 at 17:25
-
3
Then, you simply cannot EVER synchronously return the
total
fromgetTotal()
because it simply isn't done yet whengetTotal()
returns. You will need to either havegetTotal()
return a promise and resolve that promise when thetotal
is done being calculated or havegetTotal()
take a callback and call that callback and pass it the total when it's done calculating. You have to restructure it. – jfriend00 Commented Apr 7, 2014 at 17:29
2 Answers
Reset to default 6The other (now deletec) answer has the right idea but bulky and incorrect promise code. Using $q.all
(Which is Promise.all in ES6 plaint promise implementations is how we wait for an array of promises to plete:
function getTotal() {
// we return the continuation here
return ptor.findElements(protractor.By.className('col33')).then(function(cells) {
// wait for all cells
return $q.all(cells.map(function(cell){ return cell.getText()}));
}).then(function(cellTexts){
return cellTexts.reduce(function(x,y){ return x + Number(y);},0);
});
}
Alternatively, if you're not an Array#reduce
fan you can sum with a for loop.
Then, usage is something like:
getTotal().then(function(total){
alert(total); // total value available here
});
Note, an external promise library like Bluebird would let you do:
return Promise.cast(ptor.findElements(protractor.By.className('col33')))
.map(function(cell){ return cell.getText(); })
.reduce(function(x,y){ return x+Number(y); });
Which is even cleaner.
Protractor has a buil-in map function.
I would remend you to do something like this:
function getTotal() {
// The same as element.all(by.css('.col33')). It will return
// a promise that resolves to an array os strings.
return $$('.col33').map(function(cell){
return cell.getText();
}).
then(function(values){
// Values is an Array.<string> parse the ints and return the value.
var result = 0;
values.forEach(function(val){
result += parseInt(val, 10);
});
return result;
});
};
getTotal.then(function(total) {
});
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745098308a4611116.html
评论列表(0条)