0

In my protractor app, I have the below method which is supposed to return boolean value, depending if it finds the element or not.

async getTheValueOfEntery(entery: string) {
  var value = await element(by.xpath(entery))
    .isPresent().then((isExist) => {
      isExist;
    });
  return value;
}

But, the problem is, it always rerturns undefined, although i am sure, it should return true.

So, what is wrong in my method?


Update:

Indeed, i need to have a chain of calling, fat functions, so the most complete version of my function is as below:

async getTheValueOfEntery(entery: string) {

  var value = await element(by.xpath(entery))
    .isPresent().then((isExist, entery: string) => {
      isExist ? element(by.xpath(entery)).getText() : 0;
    });

  return value;
}

But, i am not able to pass entery:string to the second lambda.

t.niese
  • 39,256
  • 9
  • 74
  • 101
Jeff
  • 7,767
  • 28
  • 85
  • 138
  • Why are you doing `.then((isExist)=>{isExist;});` at all, what are you trying to achieve with that? Avoid [`await`ing a `.then(…)` chain](https://stackoverflow.com/a/54387912/1048572)! – Bergi Feb 03 '19 at 13:13
  • 1
    Yes, but still you should be doing simply `const isExist = await element(by.xpath(entery)).isPresent(); if (isExist) return Number(await element(by.xpath(entery)).getText()); else return 0;`. – Bergi Feb 03 '19 at 13:39
  • If you have a new question then ask a new one but don't change your original question to something else. This makes all other answers that tired to solve your original question wrong. – t.niese Feb 03 '19 at 14:05

3 Answers3

1

Pay attention to this:

then((isExist)=>{isExist;});

In JavaScript fat arrow functions, if you embrace your code with curly brackets, then you need to return a value:

const sum = (a, b) => {
  return a + b;
}

Instead, if you only have a row, you can drop both curly brackets and return statement:

const sum = (a, b) = a + b;

So, also in your case, you can decide if to add return before isExist, or if to remove the curly brackets.

But let's go further, if you only have a parameter, you can also drop round brackets:

const square = x => x * x;

So your code would look like this:

.then(isExist => isExist);

But this doesn't mean much! You are just returning the parameter that you get in input, and it won't change your promise value.

In the end, you can simplify your code in this way:

async getTheValueOfEntery(entery:string){
    return (await element(by.xpath(entery))).isPresent();
}

Ps. It's preferred to talk about fat-arrow functions in javascript, rather than lambda!

  • Your final example is awaiting `isPresent` and that is not async. You need parentheses. – Steven Spungin Feb 03 '19 at 12:04
  • It is just called arrow function. You probably call it fat arrow if you come from the context of coffescript. But the ECMA Script Specification name them just [arrow function](https://www.ecma-international.org/ecma-262/9.0/index.html#sec-arrow-function-definitions). – t.niese Feb 03 '19 at 15:39
  • @t.niese yeah, but when it was introduced everyone called it "fat arrow functions", maybe to always remember the shape! – Christian Vincenzo Traina Feb 03 '19 at 16:10
1

You don't return anything from your arrow function, so the resul of it is undefined. If you write:

.isPresent().then((isExist, entery: string) => {
  isExist ? element(by.xpath(entery)).getText() : 0;
});

then it is as if you would write:

.isPresent().then(function (isExist, entery: string) {
  isExist ? element(by.xpath(entery)).getText() : 0;
});

So you need to add a return:

.isPresent().then((isExist, entery: string) => {
  return isExist ? element(by.xpath(entery)).getText() : 0;
});

Or remove the {}:

.isPresent().then((isExist, entery: string) => isExist ? element(by.xpath(entery)).getText() : 0);

And if you don't do anything with the value variable except of returning it, then you don't need to use await. You could just write:

async getTheValueOfEntery(entery: string) {

  return element(by.xpath(entery))
    .isPresent().then((isExist, entery: string) => {
      isExist ? element(by.xpath(entery)).getText() : 0;
    });
}

The async would then in theory also not required, but it does not harm and it will show that this function will always return a Promise.

t.niese
  • 39,256
  • 9
  • 74
  • 101
  • @KamyarParastesh your original question is about `async/await is always returning undefined` and bot about that error you mention, that's a completely different topic. – t.niese Feb 03 '19 at 12:24
  • Could you please review my question once more? @t.niese Sorry, i temprarily removed the accepted answer, so i can get help from more people. i applogize for it. – Jeff Feb 03 '19 at 13:22
-1

The return from await is really the then param. You don't need the then at all. The result of the then is what is returning undefined.

var value = await (element(by.xpath(entery))).isPresent()
return value;

Also, I am not sure what is async here. You might be awaiting the wrong object.

var value = await (element(by.xpath(entery))).isPresent()
return value;

or

var ele = await element(by.xpath(entery))
return ele.isPresent()

or

var ele = await by.xpath(entery)
return element(ele).isPresent()

updated

var isExist = await element(by.xpath(entery))
        .isPresent()
var value = isExist ? await element(by.xpath(entery)).getText() : 0;
        });

      return value;

It's still not clear what you are awaiting though.

Steven Spungin
  • 27,002
  • 5
  • 88
  • 78
  • You dont use await and then together. You just await again. – Steven Spungin Feb 03 '19 at 12:14
  • `Your code is returning before the then is even executed.` where should that be the case in the code the OP shows? The `await` waits for the promise return by the chained expression (so the one returned by the last `.then`) – t.niese Feb 03 '19 at 12:25