Cannot access a Typescript method variable within an inline function

I've encountered an issue with my code involving loading values into the array usageCategory within an inline function. Despite successfully adding values to the array inside the function, I am unable to print them outside it.

getAllUsageCategoryElements(){

        var usageCategory: string[] =  [];

        var that=this;

        // Extracting all droplist elements to validate 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 log statement works fine but pushing value to the array doesn't

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

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

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

How can I resolve this issue and access the array values outside the inline function? Any assistance would be greatly appreciated.

Answer №1

Learn how to use ElementArrayFinder.prototype.map

If you're looking to convert an ElementArrayFinder object into a list of objects that you create, consider using the .map function. This handy method allows you to easily transform your elements. For more details, check out the documentation at http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.map. In the example provided by Protractor, the map function returns a list of objects. For your specific scenario, make sure to await the text of the element and return it within the map callback function.

async getAllUsageCategoryElements() {
    // Extract all droplist elements and store them in an array for validation.
    const spans = this.addAdditionalCostDialogue.usageCategoryDropListContainer
        .all(by.tagName('li')).all(by.tagName("span"));
    // Use map on the ElementArrayFinder to obtain 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}`);
    }
}

Answer №2

There are a couple of issues in the code you provided:

1) The variable usageCategory is defined as a local variable, not as a property of the function getAllUsageCategoryElements. Therefore, you should use usageCategory.push(text); instead of that.usageCategory.push(text);.

2) The method getText() is asynchronous, meaning that any synchronous code following it will be executed before the result of getText() is available. To ensure the correct order of execution, you should place the synchronous code inside a then() block after the getText() call.

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

Here's the corrected version of the code:

getAllUsageCategoryElements(){

    var usageCategory: string[] =  [];


    // Extract all droplist elements and store them in an array for validation.
    this.addAdditionalCostDialogue
        .usageCategoryDropListContainer
        .all(by.tagName('li'))
        .all(by.tagName("span"))
        .each(function (element, index) {

            element.getText().then(function (text){
                usageCategory.push(text);
            })
    })

    .then(function(){

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

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

        return usageCategory;
    });

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble initializing Google Maps in an Angular directive

I'm currently working on integrating the Google Maps API into an Angular website, but I'm encountering initialization issues. Within my HTML page, I'm utilizing bootstrap nav nav-tabs and switching between tabs using an Angular controller. ...

How can Observables be designed to exhibit both synchronous and asynchronous behavior?

From: Understanding the Contrasts Between Promises and Observables In contrast, a Promise consistently operates asynchronously, while an Observable can function in synchronous or asynchronous manners. This presents the opportunity to manipulate code in ...

Sleek dialog sliding animation with Svelte

I'm struggling with a svelte component that I have and I'm trying to implement a slide down animation when it closes. The slide up animation is functioning correctly, but for some reason the slide down animation is not working. Does anyone have a ...

Error receiving by React while updating an array with setState() in TypeScript

I am in search of a way to adjust a property of an item within an array by using the updater returned from setState. The function is passed down as props to the child, who then invokes it with their own index to update their status. const attemptToUpdate ...

TypeScript PatchBaseline with AWS CDK

I am currently working with the AWS CDK and TypeScript, utilizing the @aws-cdk/aws-ssm library to create a PatchBaseline. While I have successfully created the Patch baseline, I'm encountering difficulties when attempting to define approvalRules. I ca ...

What is the best method for extracting html-string from html-string across different browsers?

Works perfectly in Chrome and FF, but encountering issues with Safari. var content = '<div><span><p>Can you catch me?</p></span></div>'; content = $.parseXML(content); var span = $(content).find('span&apo ...

How can I retrieve a certain type of object property in TypeScript?

Imagine having a collection of flags stored in an object like the example below: type Flags = { flag1: string, flag2: string, flag3: boolean, flag4: number } // const myFlags: Flags = { // flag1: 'value 1', // flag2: 'value 1&ap ...

Eliminate incorrect or invalid state when resetting a dropdown in an Angular ng-select component

I have integrated the ng-select plugin into my Angular project for handling dropdowns. One specific requirement I have is to reset the second dropdown when the first dropdown is changed. Below is a snippet of the code: <ng-select [items]="branchMo ...

Generate a key pair using the cryto library and then use it with the json

There's a new method called generateKeyPair in node 10, and I am utilizing it in the following way: const { publicKey, privateKey } = crypto.generateKeyPairSync("rsa", { modulusLength: 4096, publicKeyEncoding: { type: "spki", format: "pem ...

How do you trigger the playback of a specific audio file when a user clicks on it?

I'm currently working on an interactive music app that mimics the functionality of a piano. Users are able to click on different boxes on the screen, triggering a unique musical note to play. While I initially considered manually collecting all the I ...

The error code TS2345 indicates that the argument type 'Event' cannot be assigned to a parameter type 'string'

Hello, I'm a newcomer to utilizing Angular and I'm struggling to identify where my mistake lies. Below is the TypeScript code in question: import { Component } from '@angular/core'; @Component({ selector: 'app-root' ...

Leveraging shadow components with the Next.js pages directory

I am facing an issue with getting a simple shadcn button to work because I am unable to import the button. Although I am using nextjs 13, I am still utilizing the pages directory. Below is the process of how I installed shadcn. Here is the installation co ...

Listening to multiple events in AngularJS using `$scope.$on`

I am faced with a situation where I need to respond to two different events being transmitted via $scope.$emit and take action only when both have occurred. For example, if the events are triggered in the following sequence: $scope.$emit('first&apos ...

inserting a dynamic variable into a JSON string

My goal is to create a javascript object, var systemName = {"system" : varA}; However, I want the object to be structured like `{"system" :"varA"} where varA contains the variable value but is enclosed in double quotes. I attempted {"system" : "'+ ...

What is the most efficient way to execute useEffect when only one specific dependency changes among multiple dependencies?

My main objective is to update a state array only when a specific state (loadingStatus) undergoes a change. Yet, if I include solely loadingStatus as a dependency, React throws an error requesting all dependencies [loadingStatus, message, messageArray, set ...

How can I transform the overall value into a percentage in Vue.js or JavaScript?

Is there a way to create a progress bar in VueJS 3 with Nuxt Js by converting the total value to a percentage and displaying it as a style width value? For example, if 40% out of 100% equals 400USD out of 1000USD, can we achieve this using a function in an ...

Error: n.indexOf function is not defined - Issue with Firebase

After integrating Stripe into Firebase, I encountered an issue where a specific line of code is supposed to execute whenever a user upgrades their plan. This code should create checkout sessions in the users' collection, but it throws an error instead ...

The click event for getelementbyid() function is malfunctioning

I need assistance with a website I am creating that plays audio when a certain condition is met. Specifically, I want the audio to play if x falls within a specific range of numbers, but also continue playing if x does not fall within that range after th ...

What is the process for including or excluding a class from a horizontal scrollbar?

I've been trying to implement a back to top button on a horizontally scrolling page. However, I'm encountering difficulties in adding or removing the necessary class to show or hide the button. Here's the JavaScript code I'm using: $( ...

When using angularjs, the $window.location.href may cause the page to load without any

I have a dilemma where I have linked all my CSS and JS files in the index.html file, but subpages are located in a templates directory. When using $window.location.href, only a plain HTML page is returned without any CSS styles. The page renders fine when ...