Loop within a promise results in undefined

Within my application, there is a function that returns a promise. Inside this function, I wait for an image in the DOM to become available and then extract that element to generate base64 data from it.

getCodesOfOneMerchant(merchantDataEntry: MerchantData) {

    var codesOfMerchant = [];

    return new Promise(async (resolve, reject) => {

      for (let index = 0; index < merchantDataEntry.qrPayloadList.length; index++) {

        const value = merchantDataEntry.qrPayloadList[index];
        const payLoad = value.qrPayload;
        this.qrvalue = payLoad;

        while (!document.querySelector(".qrcode img")) {
          await new Promise(r => setTimeout(r, 500));
          console.log("waiting for qr");
        }
        console.log("QR element is available");
        const qrEle = document.getElementById('qrcode');
        let imgBase64Data = this.getBase64Image(qrEle.firstChild.firstChild);

        console.log('Base64 = ' + imgBase64Data);

        var qrName = merchantDataEntry.serviceName + "-" + value.branch + "-" + value.mobile;

        let userQr: UserQr = new UserQr();
        userQr.name = qrName;
        userQr.qr = imgBase64Data;

        codesOfMerchant.push(userQr);
        console.log('1')
        
        if (index == merchantDataEntry.qrPayloadList.length - 1) {
          resolve();
        }
      }
      console.log('2')
      console.log('Returning data = ' + JSON.stringify(codesOfMerchant));
      return codesOfMerchant;

    });
}

The following function calls the above one:

async downloadQrCodesOfAllSelectedMerchants() {

    var qrCodesForAllMerchants = [];

    const filteredData = this.merchantDataList.filter(entry => entry.qrSelected);

    const promises = filteredData.map(async (value) => {
      const qrCodesOfMerchant = await this.getCodesOfOneMerchant(value);
      return qrCodesOfMerchant;
    });

    const qrCodesOfAll = await Promise.all(promises);

    console.log('HELLO');

    console.log(qrCodesOfAll); // this prints undefined

 
    console.log('DONE')
}

Although I have returned the promise inside the first method, the calling function still receives undefined. I cannot understand what is wrong there.

As you can see, I just log the data to return to the console inside the second function just before returning. The data is there.

Could someone please assist me with this issue? Thank You..!

Answer №1

It is advisable to eliminate the

return new Promise(async (resolve, reject) => {
line and instead convert the getCodesOfOneMerchant function itself into an async function:

async getCodesOfOneMerchant(merchantDataEntry: MerchantData) { /*
^^^^^ */
  const codesOfMerchant = [];
  for (const value of merchantDataEntry.qrPayloadList) {
    this.qrvalue = value.qrPayload;

    while (!document.querySelector(".qrcode img")) {
      await new Promise(r => setTimeout(r, 500));
      console.log("waiting for qr");
    }
    console.log("QR element is available");
    const qrEle = document.getElementById('qrcode');
    let imgBase64Data = this.getBase64Image(qrEle.firstChild.firstChild);
    console.log('Base64 = ' + imgBase64Data);

    const userQr: UserQr = new UserQr();
    userQr.name = merchantDataEntry.serviceName + "-" + value.branch + "-" + value.mobile;
    userQr.qr = imgBase64Data;

    codesOfMerchant.push(userQr);
  }
  return codesOfMerchant;
}

Answer №2

When looking at the callee function within this code snippet

const promises = filteredData.map(async (value) => {
  const qrCodesOfMerchant = await this.getCodesOfOneMerchant(value);
  return qrCodesOfMerchant;
});

You are currently awaiting the response of the getCodesOfOneMerchant method, which will resolve the promise right there.

Instead of that, you can simply store all the promises in the 'promises' array and then await all of them at once using Promise.all(promises)

const promises = filteredData.map(value => this.getCodesOfOneMerchant(value))
const qrCodesOfAll = await Promise.all(promises);

This will give you 'qrCodesOfAll' as an array of resolved promises

Furthermore, the executor function is returning a promise but it is never being resolved. The resolved values from the promise, such as 'codesOfMerchant', will not be received by the callee as they should. To fix this issue, you need to explicitly resolve the promise with

resolve(codesOfMerchant)

This will ensure that the value of 'codesOfMerchant' is properly returned to the callee

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

Continuous HTTP Stream Observable that only transfers data without emitting any other items

I've encountered an issue while working with Angular 4 and RxJS. In my code, the Observable generated by the http.post request is not passing any data to the subsequent map() function. The POST request seems to result in an endless stream of Motion JP ...

Creating an asynchronous function in Node.js that returns a promise, but experiencing unexpected behavior when using console.log to display the result

Recently, I created a simple and compact API that determines the gender of a person. It functions by sending a get-request to a specific page which responds with a JSON object. This snippet illustrates how my module works: 'use strict'; const ht ...

How can I access an array option that combines both global and target-specific specifications within a grunt plugin?

Currently, I am in the process of creating a grunt plugin that includes options which can consist of arrays of values. These values are specifically file paths (distinct from the files listed in the task's own 'files' property). The setup fo ...

Is there any drawback in transforming Observables into promises?

There are situations where subscribing in a component is necessary instead of using an async pipe. In scenarios where only one value will be emitted by the observable, is there any drawback or downside to converting it to a promise? If we are not subscrib ...

Utilizing AngularJS ng-messages feature across various languages

Utilizing ng-messages to show error messages for form validation in my application. I have a multi-language app, how can I implement ng-messages to support multiple languages? HTML Form <div class="messages" ng-messages="myForm.email.$error"> & ...

AngularJS 1 - CSS glitch occurs when navigating between tabs

Upon loading my homepage, it appears as follows: Initially, certain rows were filled with a blue background color using ng-class, specifically "row-answered-call" as shown below: <tr ng-repeat="item in list" ng-class="{'row-answered-call': i ...

Async Laziness Loading

At the moment, our team is utilizing the SAP HANA Database for data storage. We plan to retrieve this data using a Node.JS-API through AJAX calls in order to take advantage of asynchronous processing. However, we have encountered a challenge: Across multi ...

An individual in a chat App's UserList experiencing issues with incorrect CSS values. Utilizing Jquery and socketio to troubleshoot the problem

Currently, I am testing a new feature in a chat application that includes displaying a user list for those who have joined the chat. The challenge is to change the color of a specific user's name on the list when they get disconnected or leave the cha ...

Effective monitoring of dependencies in a personalized connection

My goal is to implement a method to visually filter table rows generated by the foreach binding. I want the filtered out rows to be hidden instead of removed from the DOM, as this can greatly improve rendering performance when filter conditions are changed ...

Deploying AngularApp with Cordova on iOS results in a blank screen

Encountering a White Screen Issue on iOS While Trying to Load an Angular App with Cordova. After modifying the base href to "./" in my Angular app project, it runs smoothly on all platforms except for iOS. Any ideas why it's not loading properly on iO ...

Encountered an error while attempting to upgrade to the latest @angular/cli version 1.0.0: Unexpected symbol "<" found in JSON at the beginning of the file

When I was using angular-cli 1.0.0 beta 23, my service was able to fetch a local JSON file for testing without any issues. However, after upgrading to angular/cli 1.0.0, I encountered the following problem: GET http://localhost:4200/json/inputInventory/ ...

Angular2: Filtering an array based on the presence of items in another array

Looking to selectively filter out entries from an object array based on certain id values within another array. I've experimented with different methods but haven't found a solution that works yet. List of id´s: list = [1,3] Array to be filte ...

What is the best way to display an image in HTML?

I have successfully created an autocomplete search box that retrieves product names, but I am struggling to display the product photos. Here is the code snippet I am using: <asp:TextBox ID="txtContactsSearch" runat="server" Width="261"></asp:Text ...

Discovering the specific style within an inspect-element and transferring it to a JavaScript file

As a novice in the realm of react/javascript, I encountered a situation where I successfully edited a specific style using the inspect element tool. However, despite my efforts, I struggled to locate the corresponding style within the Javascript file. Ha ...

Toggle the visibility of an input field based on a checkbox's onchange event

I am facing a challenge where I need to display or hide an Input/Text field based on the state of a Checkbox. When the Checkbox is checked, I want to show the TextField, and when it is unchecked, I want to hide it. Below is the code snippet for this compon ...

Error encountered in Vue 3 typescript: Uncaught TypeError - this.$on function is not defined in this context

Just set up a fresh installation of Vue 3 using vue-cli and typescript. Everything seems to be running smoothly, but as soon as I incorporate the https://vue-select.org/ package, I encounter this error in the browser console: Uncaught (in promise) TypeErro ...

When moving to a different route inside the router.events function, the browser becomes unresponsive

Within my top navbar component, I have set up a subscription to the router events: this.router.events.subscribe(event => { if (event instanceof RoutesRecognized && this.authService.isLoggedIn()) { // additional custom logic here: ...

"Uh-oh! Encountered a new unexpected runtime error. Can't seem

While working on my portfolio in Next.js, I encountered an issue. I added a header to display on all pages by placing it in _app.js without making any changes to _document.js. Here is the error message: Unhandled Runtime Error Error: No router instance fo ...

Backbone "recalling" stored data in attributes

Presented here is a basic model: myTestModel = Backbone.Model.extend({ defaults: { title: 'My Title', config: {}, active: 1, } }) While nothing particularly stands out, there is an interesting observation regardi ...

What is the best way to implement Angular 2 slash routes in conjunction with Node Express?

I have defined some routes in my App component: @routeConfig([ { path:'login', name: 'Login', component: Login }} Additionally, I have a basic node express loader set up: var express = require('express'); var ...