0

I have the below code where I am loading values to the array usageCategory in an inline function. But when I try to print the values outside this function, nothing gets printed.

getAllUsageCategoryElements(){

        var usageCategory: string[] =  [];

        var that=this;

        // extract all the droplist elements and put into an array so that I can validate them from another page.
        this.addAdditionalCostDialogue.usageCategoryDropListContainer.all(by.tagName('li')).all(by.tagName("span")).each(function (element, index) {
            element.getText().then(function (text){

                 //console.log("printing directly " + text);
                // the above code works fine and prints all the drop list contains but when I try to add it to an array

                that.usageCategory.push(text);
            })
        });

        console.log("Size of the array is " + usageCategory.length);

        usageCategory.forEach(element => {
            console.log("Printing text " + element);
        });
    }

What am I doing wrong here? How can I access these array values outside the inline function? Any help would be much appreciated.

AnOldSoul
  • 4,017
  • 12
  • 57
  • 118
  • Similar issue: https://stackoverflow.com/questions/54334368/unable-to-access-array-variable-from-inside-a-function – Rochan Jan 23 '19 at 22:30
  • `usageCategory` is a local variable, not a property of the function `getAllUsageCategoryElements `, so you should not use `that.usageCategory.push(text);` , just use `usageCategory.push(text);` – yong Jan 24 '19 at 02:07

2 Answers2

0

Using ElementArrayFinder.prototype.map

This might be a good time to use the .map function since it will convert the ElementArrayFinder object to a list of objects you create. http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.map In the Protractor example (in the link), the map returns a list of objects. For your case, you'll need to await the text of that element and return it in the map callback function.

async getAllUsageCategoryElements() {
    // extract all the droplist elements and put into an array so that I can validate them from another page.
    const spans = this.addAdditionalCostDialogue.usageCategoryDropListContainer
        .all(by.tagName('li')).all(by.tagName("span"));
    // Map over an ElementArrayFinder to get a list of returned items from
    // map operation. In this case, we are returning a list of strings
    const usageCategories = await spans.map(async (el) => {
      const text = await el.getText();
      // console.log(`printing directly ${text}`);
      return text;
    });

    console.log("Size of the array is " + usageCategories.length);
    for (let usageCategory of usageCategories) {
      console.log(`printing text ${usageCategory}`);
    }
}
cnishina
  • 5,016
  • 1
  • 23
  • 40
0

There are two issues in your code:

1) usageCategory is a local variable, not a property of the function getAllUsageCategoryElements , so you can't not use that.usageCategory.push(text); , just use usageCategory.push(text);

2) getText() is Async API, following Sync code will be executed prior to the getText(),
so the usageCategory.length is 0 when executing. You need to put these Sync code in a next then() behind getText() to make them be execute later then getText().

console.log("Size of the array is " + usageCategories.length);
for (let usageCategory of usageCategories) {
  console.log(`printing text ${usageCategory}`);
}

Corrected code:

getAllUsageCategoryElements(){

    var usageCategory: string[] =  [];


    // extract all the droplist elements and put into an array so that I can validate them from another page.
    this.addAdditionalCostDialogue
        .usageCategoryDropListContainer
        .all(by.tagName('li'))
        .all(by.tagName("span"))
        .each(function (element, index) {

            element.getText().then(function (text){
                //console.log("printing directly " + text);
                // the above code works fine and prints all the drop list contains but when I try to add it to an array
                usageCategory.push(text);
            })
    })

    .then(function(){

        console.log("Size of the array is " + usageCategory.length);

        usageCategory.forEach(element => {
            console.log("Printing text " + element);
        }); 

        return usageCategory;
    });

}
yong
  • 13,357
  • 1
  • 16
  • 27