Is it optimal to have nested promises for an asynchronous file read operation within a for loop in Node.js?

The following Node.js function requires:

  • an object named shop containing a regular expression
  • an array of filenames

This function reads each csv file listed in the array, tests a cell in the first row with the provided regular expression, and returns a new array of matching filenames.

function matchReport(shop, arr) {

    return promise = new Promise(resolve => {
        var newArray = [];
        for(var j=0;j<arr.length;++j) {
            let filename = arr[j];
            csv()
            .fromFile(filename)
            .then(reportData => {
                if (reportData[0]['Work'].match(shop.productRegex)) {
                    newArray.push(filename);
                }
                if (j === arr.length) {
                    resolve(newArray);
                }
            });
        }
    }).then(matches => {
        return {
            'shop' : shop.name,
            'reports' : matches
        }
    }).catch(e => {
        console.log(e);
    });
}

Occasionally, the function will output the desired result as shown below:

{ shop: 'shop1',
  reports: [ '../artist-sales-report-2020-11-12(1).csv' ] }
{ shop: 'shop2',
  reports:
   [ '../artist-sales-report-2020-12-03.csv',
     '../artist-sales-report-2020-09-01.csv' ] }

However, more often than not, it results in missing reports, like this:

{ shop: 'shop1',
  reports: [ '../artist-sales-report-2020-11-12(1).csv' ] }
{ shop: 'shop2',
  reports: [ '../artist-sales-report-2020-12-03.csv' ] }

I have identified that the issue lies within the asynchronous nature of the csv reportData block. I have attempted various solutions involving if..then or switch statements to no avail. While creating additional promises within this one may seem cluttered, I have yet to find success with that approach as well.

Answer №1

By utilizing the power of async/await and eliminating nested promises, you can streamline your code into a more concise form as shown below. It seems like the core issue lies within the fromFile method, which appears to be asynchronous in nature due to its usage of then without proper awaiting.

async function generateShopReport(store, files) {
    
    const results = await Promise.all(files.map(async file => {
       
        const data = await csv().fromFile(file);

        if (data[0]['Product'].match(store.productPattern)) {
        
            return file;
            
        }
        
    }));
    
    return {
        'store': store.name,
        'matchingReports': results.filter(Boolean)
    };

}

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

Using parameters in Express.js/Node.js middleware

I am currently working on a nodeJS project where I need to pass parameters in middleware for validation purposes within the code. Here is an example of the middleware that I have created: 'use strict'; // eslint-disable-next-line no-unused-vars ...

Utilize inline scripts within the views of Yii2 for enhanced functionality

I stumbled upon a jQuery code online that allows for the integration of Google Maps, and I'm looking to implement it in my application to ensure accurate address retrieval. You can find the jQuery code here. Currently, I am working with yii2 Advanced ...

Utilizing Firebase 9.0.1 Functions in Vue.js 3

As a newcomer to Vue, I decided to tackle my second tutorial which involved integrating Firebase backend with Vue. However, the tutorial was based on Vue 2 and an older version of Firebase. Determined to stay current, I set out to replicate the project usi ...

Is it possible to use async in the onChange handler of a React event?

Can async be used to pause execution until a function completes within an onChange event? Here is an example: const onChange = async (e) => { console.log(current[e.target.name]); await setCurrent({ ...current, [e.target.name]: e.targe ...

Attempting to establish a connection with Redis through the combination of TypeScript and Node.js

Currently, I am attempting to establish a connection with Redis using TypeScript and Node.js. However, I am encountering an issue where **error TS2693: 'RedisStore' is designated as a type but is being utilized as a value in this context.** let r ...

Creating a Node.js application with a npm start script

I am completely new to working with nodejs. Within my dockerized setup, I aim to integrate appdynamics support for nodejs applications. This requires each app to include the following as the first line within their code: require("appdynamics").profile({ ...

Identifying the hashKey and selected option in a dropdown menu

My attempt to set the selected option for the select menu is not working because the data in the ng-model that I am sending has a different $$hashKey compared to the data in the select menu, and the $$hashKey holds the values. <select class="form-contr ...

Leveraging the html-webpack-plugin for creating an index.html file within Webpack (specifically in a project based on the vue-simple boiler

For every build in Webpack, I am attempting to create a customized index.html file. In order to achieve this, I have incorporated html-webpack-plugin. I comprehend that to generate an index.html file within my dist directory, the following configurations ...

Encountering the issue of "TypeError: Cannot read property 'file' of undefined" when trying to upload a video with Multer

The objective is to select a video file from the desktop and upload it to the platform. The uploaded video file will then be automatically posted to a specified Youtube channel using GCD. An error message I encountered is:"react-dom.development.js:40 ...

Halt the execution of a function upon clicking a div element

I'm currently working on a function that needs to be stopped when a div with the class "ego" is clicked. This function toggles the visibility of the header based on the scroll position and should only run by default. Below is the code snippet: $("#e ...

Can a function be called when using ng-options with AngularJS select?

Here is some HTML code <select ng-model="selectedMarker" ng-options="shape.text for shape in Selects('shapes')"> </select> And below is the JavaScript code angular.module('todo', ['ionic']) . ...

Creating a dynamic dropdown menu using JQuery that does not automatically submit the form when a value is

Upon selecting a background color from the dropdown menu, I am generating a dynamic dropdown for text colors. The Text Color dropdown is populated correctly based on the selection of Background Color. Although the functionality works as intended, I encoun ...

When refreshing the page, the authentication token set in the Vuex store using axios in Nuxt.js/Vue.js gets reset

Here is the code snippet I am using to manage login, logout, user retrieval, and token setting for all axios requests as an auth header. While this code works perfectly during client-side rendering - such as logging in, storing the token in cookies, etc. ...

Importing a MATLAB table file into a Node.js environment and converting it into an array

Currently in the process of setting up a test server for a Web-Application, where fake data needs to be transmitted via a Websocket. The fake data is stored in a MATLAB table file (.mat), which essentially consists of a 4000*192 array. My goal is to conver ...

Creating a dynamic word cloud in D3: Learn how to automatically adjust font sizes to prevent overflow and scale words to fit any screen size

I am currently utilizing Jason Davies' d3-cloud.js to create my word cloud, you can view it here 1. I'm encountering an issue where the words run out of space when the initial window size is too small. To address this, I have a function that cal ...

Troubleshooting a Socket.IO Express Demo glitch on Mac OS X Mountain Lion

I found this piece of code on https://github.com/LearnBoost/socket.io and decided to use it as a starting point for my Socket.IO and Express example. However, when I try to access localhost, I encounter the following error: Cannot GET / This is what my ...

Node.js Antivirus Scanning for a Uploaded File Stream

Seeking an antivirus solution for scanning the filestream uploaded from a rest api using express. Came across clamscan as an option, but it requires some linux dependencies. https://www.npmjs.com/package/clamscan Is there a more efficient method to perfo ...

Angular may encounter compatibility issues when running on a page that has been loaded using

In my Sails project's homepage.ejs view, I utilize Ajax to dynamically load a portion of the page using the "food" controller's "show" action. This results in loading the show.ejs file located at /views/food/show.ejs. $('#outerDiv').lo ...

Fade-in a new, revised text after fading-out the original text in ReactJS

I have a bunch of p elements that I'd like to cycle through, fading in one at a time and then replacing it with the next. Here is the jQuery example on CodePen: https://codepen.io/motion333/pen/EBBGVM Now, I'm attempting to achieve the same effe ...

Store the selected checkbox values in an array when submitting in Ionic

One issue I am facing is that the checked checkboxes are returning true instead of the value of input (type="checkbox"). Array displaying responded checked or unchecked items I am unable to store this data in an array as needed. Additionally, I cannot sp ...