3

A bit new to javascript, but from what I've read, all values within a promise are basically only usable within that promise right?

Basically getSomething() returns true/false from another promise. And I was to break out of the for loop if true. I tried something like this, but I'm sure it's not right as it's not printing out "breaking"

for(...) {
    var bool = this.getSomething(a,b,c).then((flag) => {
        if (flag == true) {
            console.log('returning true');
            return true; // can't use break so have to set boolean - eslint gives me unsyntactical break
        }
    });

    if (bool == true) {
        console.log('breaking');
        break;
    }
}

getSomething(a,b,c) {
    const n = b[a].element(by.binding('something'));
    return n.getText().then((text) => {
        if (text === c) {
        return clickSomething();        // returns true after click()
        }
    });
}

The reason I'm using the for loop is because I need to find a matching text in the strong tag, then click on the button in the td tag below it.

<tbody>
    <tr ng-repeat="something">
        <td>
            <strong>{{x.name}}</strong>
        </td>
        <td>
            <button>{{x.button}}</button>
        </td>
    </tr>
</tbody>
5
  • You can't use promises with a for loop. Promises are asynchronous, meaning they'll run only after all of your other synchronous code runs. Commented Jan 15, 2016 at 20:59
  • @MikeC why after? They will run in the same time. Commented Jan 15, 2016 at 21:01
  • @Calin What I mean is that the .then function won't execute until after all synchronous code has complete. Same idea as using setTimeout or setInterval. Commented Jan 15, 2016 at 21:02
  • @MikeC then will return a new promise, the callback function (it has a syntax error) in then will get executed once somebody calls resolve on this promise, nobody does that in this code. I think the poster needs to do some more readup on promises. Commented Jan 15, 2016 at 21:13
  • 1
    @Calin The then callback is fine. It's an arrow function. Yes, it would return a promise which explicitly means the value won't be accessible in time to break out of the loop. See alecxe's answer. Commented Jan 15, 2016 at 21:16

2 Answers 2

6

There are promises involved, which Protractor adds to the Control Flow queue, you cannot read and handle the for loop + break as you would usually do in a synchronous "top to bottom" code.

The common solution to this problem is to use recursion+closures, see sample solutions here:


The reason I'm using the for loop is because I need to find a matching text in the strong tag, then click on the button in the td tag below it.

One option would be to use the by.xpath() locator:

element(by.xpath("//td[strong = '" + label + "']/following-sibling::td/button")).click();

where label is the strong value you are looking for.

Or, a more protractor-specific approach would be to use filter():

var rows = element.all(by.repeater("something"));

var filteredRow = rows.filter(function (row) {
    return row.element(by.binding("x.name")).getText().then(function (name) {
        return name === label; 
    });
}).first();

filteredRow.element(by.binding("x.button")).click();
Sign up to request clarification or add additional context in comments.

2 Comments

Can you take a look at my update? I took a look at your answer stackoverflow.com/a/31208548/4188135 and others, but they seem to apply to instances where the click() action is performed on the row/tag that matches. But I need to somehow do the action on the second row returned by repeater. Hope that makes sense
@yob-v-u sure, thanks for making the problem more specific. Updated the answer, hope it helps.
1

If you really want to do something like this you will have to use when, it will return a new promise.

when(promise1, promise2, promise3).done( function (promise1, promise2, promise3) {
}
  • When all the given promisses are resolved, the new promise is resolved
  • When one promise fails, the new promise fails

1 Comment

thanks, could you share more examples of when usage? maybe a link

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.