2

I am novice to javascript concepts. Why i am getting the different output for the same variable length? While it is showing the expected result inside the body ?

var length;
element.all(by.className("className")).getText().then(function(items){
    length = items.length;
    console.log("1st output = "+length);//1
    console.log("2nd output = "+items.length);//1
});
console.log("3rd output = "+length);//undefined

Output:- 1st output = 1

2nd output = 1

3rd output = undefined

shankar upadhyay
  • 883
  • 12
  • 18
  • 2
    3rd is undefined because it's an asynchronous call. – Łukasz Trzewik Oct 13 '17 at 04:51
  • 1
    `.then` works in asynchronous fashion by the time the code inside `.then` have executed the statement `console.log("3rd output = "+length)` have finished it's execution & at that time `length` is undefined.. You can check this link https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – brk Oct 13 '17 at 04:52

3 Answers3

2

Because your all() is async call so console.log will run before you finish then chain and assign value to length

Quoc-Anh Nguyen
  • 4,798
  • 1
  • 22
  • 34
1

The element.all(by.className("className")).getText()) call in your function returns something called a promise- it executes some code, and after this code is executed, it calls the function inside .then(). However, this happens independently of the rest of your program- so it continues to execute the console.log after the .then() statement.

This leads to what is called a race condition- where the order of operations can be undefined.

Derek Brown
  • 4,232
  • 4
  • 27
  • 44
1

All before answers already explain what happens and why. So it's clear, that your 3rd console.log is executed before your then() condition finishes.

What you can try is this:

var length;
element.all(by.className("className")).getText().then(function(items){
    length = items.length;
    console.log("1st output = "+length);//1
    console.log("2nd output = "+items.length);//1
});
browser.waitForAngular();  //add this line to let Protractor wait for Async tasks to be resolved first
console.log("3rd output = "+length);

However, keeping the 3rd console.log() inside the then() statement would be the more proper solution.

Ernst Zwingli
  • 1,402
  • 1
  • 8
  • 24
  • Hi, If my application is not angular can we use browser.waitForAngular() ? – Aarya Hareendranath Oct 13 '17 at 09:32
  • No, that won't work as `browser.waitForAngular()` resolves on angular-specific objects. I suggest to go with `async / await` as the pure javascript way. Protractor is going to move there within the next 12-18 months anyway. [Read all about here](https://stackoverflow.com/a/46660193/8683679) – Ernst Zwingli Oct 13 '17 at 10:24
  • @shankarDayalupadhyay : It didn't work or what was the reason for unaccepting the answer? I'd like to improve it, if I may (as it seems you still have an unanswered question). – Ernst Zwingli Oct 16 '17 at 06:47