2
browser.findElements(protractor.By.repeater('cat in cats')).then(function(rows) {
        for (i = 0; i < rows.length; i++) { //which is always 3
            var tmp = element(by.repeater('cat in cats').row(i)).element(by.binding('cat.name')).getText();
            tmp.then(function(text) {
                console.log('text is : ' + text);
                console.log('iteration number is: ' + i);
                if (text == 'someText') {
                    element(by.repeater('cat in cats').row(i)).element(by.binding('cat.action')).click();
                }
            });
        }

In this case the value of 'i' inside the function is always returning 3. I have get text and then check if the text is what I want and click on an element.

The value of 'i' in the 'if' statement is always returned as 3. Something to do with promises, but I am not sure. Any help with modified code is much appreciated.

Thanks!

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
SreeN
  • 33
  • 6

1 Answers1

4

Don't call by.repeater() multiple times; instead, use map() and "chain" the promises like this:

element.all(By.repeater('cat in cats')).map(function(elm) {
    return {
        text: elm.element(by.binding('cat.name')).getText(),
        action: elm.element(by.binding('cat.action'))
    };
}).then(function(arr) {
    for (var i = 0; i < arr.length; i++) { 
        if (arr[i].text == 'someText') {
            return arr[i].action;
        }
    }
    throw new Error('Text not found');
}).then(function(elm) {
    elm.click();
});

All of the credits go to @Andres for the solution provided here:

Also see:

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • This looks clean. But the core problem still exists. The value of 'i' in the 'if' condition is always equal to rows.length. I have found this, http://blog.jbrantly.com/2010/04/creating-javascript-function-inside.html but it's hard for me to understand. – SreeN Dec 17 '14 at 07:21
  • @SreeN yeah, it was a "closure" problem. I've updated the answer, check if it is working for you. – alecxe Dec 17 '14 at 14:54
  • No. When I print name.getText() to the console, I get [object Object]. And it is never entering the if condition. – SreeN Dec 17 '14 at 17:08
  • @SreeN ok, my bad, let's try another option - updated the answer. – alecxe Dec 17 '14 at 17:16
  • No.This implementation is clicking on all the elements for the value of 'i'. It is not honoring the condition 'text='SomeText'. – SreeN Dec 17 '14 at 18:31
  • Rollback war with yourself, eh? (No problem! Just clearing an auto flag!) – Andrew Barber Dec 17 '14 at 18:57
  • @AndrewBarber sorry for that, fighting myself ya :) Thanks. – alecxe Dec 17 '14 at 18:58
  • awesome! this worked. Thank you so much!. Also one final question: when 'someText' is not found in the array of text, elm.click() fails with this error "TypeError: Cannot call method 'click' of undefined". Is there a way we can catch that error and make the test fail gracefully. With an 'expect' may be? – SreeN Dec 17 '14 at 19:11
  • @SreeN as an option, you can throw an error after the loop, edited the answer. Or, you can use `expect(elm).not.toBeDefined()` before clicking. – alecxe Dec 17 '14 at 19:16