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

`Is there a way for Javascript to retrieve information sent from Python Flask's render_template() method?`

Issue: I am facing difficulties in retrieving and displaying the data that I send from Javascript code when the user visits the site's landing page. The data in question is a dataframe. Backend Python Code: from flask import Flask, render_template, ...

Exploring the Differences Between Next.js Script Components and Regular Script Tags with async and defer Attributes

Can you explain the distinctions between the next js <Script /> component rendering strategies such as afterInteracive, beforeInteractive, and lazyLoad, as opposed to utilizing a standard <script /> tag with attributes like async and defer? ...

Adding negative values to the Tailwind CSS utility plugin is a simple process that can greatly enhance

Adding Negative Values to Tailwind CSS Utility Plugin Quick Summary: I've developed a custom Tailwind utility plugin that includes numeric values. I'm looking for a way to introduce negative numbers by adding a - at the start of the class, simi ...

Maintaining the dropdown in the open position after choosing a dropdown item

The dropdown menu in use is from a bootstrap framework. See the code snippet below: <li id="changethis" class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown>LINK</a> <ul class="dropdown-menu"> <li id ...

"Implementing a dynamic way to assign values to different item types in React

There is an object with multiple values inside: const [sort, setSort] = useState({ "city": [], "price": [], "year": [] }); When the "add" button is clicked, the "city" value should be updated to include certain va ...

Session Redirect Error in Express.js

Encountering an error consistently when running my code with the pseudocode provided below (Just to clarify, my code is built on the react-redux-universal-hot-example) Error: Can't set headers after they are sent. [2] at ServerResponse.OutgoingMe ...

Choosing various choices using AngularJS

My goal seems simple using vanilla JS, but with AngularJS, I'm looking for the best way to achieve it within the framework. I aim to update the selected options in a multiple select box without adding or removing any options. Below is a snippet of my ...

Is it possible to incorporate a label within a dropdown menu (<select>)?

How can I add a label inside a select box using Bootstrap? Here is an example: Before selecting an option After selecting an option, the label should appear in a small size like this: After selecting an option : <div class="form-group"> & ...

Combining the elements within an array of integers

Can anyone provide insight on how to sum the contents of an integer array using a for loop? I seem to be stuck with my current logic. Below is the code I've been working on: <p id='para'></p> var someArray = [1,2,3,4,5]; funct ...

How exactly does the 'this' type in TypeScript determine its own type inferences?

When working with TypeScript, I wanted to use the this keyword to type certain properties of my class. However, I encountered a problem that I couldn't figure out how to solve. What I was trying to achieve is something like this: export class Animal{ ...

Searching for values within an array of objects by iterating through nested arrays to apply a filter

Having trouble returning the testcaseid from an array to this.filteredArray Able to fetch header value and all values of the array when the search word is empty. Seeking assistance with iterating through the testcaseid and header on the search input fiel ...

Angular JS Introductory Module

Currently, I am encountering an issue in AngularJS 1.2.15 marked by $injector:modulerr. Interestingly, the application runs smoothly when hosted on a MAMP Apache server locally, but encounters errors when running on a node server, generating the error mess ...

Retrieving Data from a JSON File in ASP.NET MVC 4

After diving into learning ASP.NET MVC 4, I dabbled in some small projects... On my index page, my goal is to fetch a JSON file containing data and showcase it on the main page. In basic HTML and JavaScript, I utilize ajax for fetching or posting JSON da ...

Causes of the error message 'TypeError: res.render is not a function'

I have set up an express application with the following code: var express = require('express'); var router = express.Router(); var passport = require('passport'); var User = require('../models/user'); var request = require(&a ...

Utilizing node.js for manipulating files (JSON) through reading and writing operations

There is an issue with my function that reads a JSON file and updates it using the fs.writeFile method. When I invoke this function multiple times, it fails to update the file properly. After the first call, it adds extra curly brackets at the end of the J ...

Fetching the second item within an object using JavaScript

I am trying to retrieve the data from the last month of an API, but I want to avoid hard-coding the date like this: const data = [data.data['Monthly Time Series']['2021-11-30']]. I need a way to dynamically access the 2nd object without ...

Receive a warning in the Heroku log stating "(node) sys is outdated. Util should be used instead" while the script is executed

I recently deployed a Node script on Heroku to be executed by a scheduler. However, upon running the script, I noticed a warning message in the logs. Dec 07 11:01:10 xxx heroku/scheduler.3255 Starting process with command `node bin/script` Dec 07 11:01:1 ...

Is there a way to display a div element just once in AngularJS?

I only want to print the div once and prevent it from printing again. $scope.printDiv = function(divName) { var printContents = document.getElementById(divName).innerHTML; var popupWin = window.open('', '_blank', 'width=300, ...

Avoid potential issues caused by cancelled asynchronous requests affecting the application's status by using the watchEffect() function

Imagine a scenario where a component receives the ID of a resource through a prop called resourceId. This component is responsible for fetching the corresponding resource from an API and displaying it, while also managing loading and error states (similar ...

I am looking to view all products that belong to the category with the ID specified in the request, and have red-colored stocks

Within my database, I have defined three mongoose models: Product, Category, and Stock. The Product model contains two arrays - categories and stocks, each including respective category and stock ids. My goal is to retrieve all products where the category_ ...