`Is it possible to set new properties or push to an array using async and await in a callback function?``

After implementing async/await with rawCollection for data retrieval within a loop, I noticed that setting new properties (poTmp) works as expected. However, once I set the new properties and try to console.log outside of the loop, the new props are not being set. Why is this happening?

let items = await Items.rawCollection()
    .aggregate([
      {
        $match: match,
      },
    ])
    .toArray()

  let data = items
  data.forEach(async item => {
    let po = await PurchaseOrderDetails.rawCollection()
      .aggregate([
        {
          $match: {
            itemId: item._id,
            tranDate: { $lte: tDate },
          },
        },
        {
          $group: {
            _id: '$itemId',
            itemDoc: { $last: item },
            onHandPO: { $sum: '$qtyBase' },
          },
        },
        {
          $group: {
            _id: '$itemId',
            itemDoc: { $last: '$itemDoc' },
            lastOnHandPO: { $last: '$onHandPO' },
          },
        },
      ])
      .toArray()
    //==================
    //set new properties
    //==================
    item.poTmp = po[0]

  })
  console.log(data)
  return data

Answer №1

The problem lies within this code snippet:

data.forEach(async item => {

When using async functions, they return promises immediately upon invocation. As a result, the forEach loop continues to execute and moves on to the console.log line.

At this point, the asynchronous tasks assigned to the async functions have not been completed yet, causing the data to remain unaltered.

If you are already within an async function (as indicated by your usage of await earlier in the code), you can handle waiting for all promises to resolve using await along with Promise.all.

Promise.all requires an array of promises, so instead of using forEach, we should utilize map to generate an array of promises.

await Promise.all( data.map(async item => { ...

In contrast to forEach, map will iterate through each item and execute the provided function. However, unlike forEach, map will produce an array containing the results of these functions, where each one returns a promise due to being async functions.

By utilizing Promise.all, we consolidate multiple promises into a single promise that resolves only when all async functions have completed. The await keyword ensures that the function halts execution until this combined promise resolves.

Halting the function with await guarantees that the console.log statement won't run until every async function has finished processing, ensuring it accesses the accurate data at that moment.

Answer №2

Below is a functional sample for anyone in need:

  async function updateBatchData(request:any,response:any){

        data = [1,3,4,5,6]

        var finalResult:number[] = [];

        await Promise.all(data.map(async item=>{

            let newRole = 'Admin';

                parameters = [
                { name: 'ID', dataType: sql.Int, value: item },
                { name: 'Role', dataType: sql.VarChar, value: newRole }
            ];

            let UpdateQuery = `UPDATE UserRoles 
                SET Role= @Role
                WHERE ID= @ID`;

            const output = await provider.execute(UpdateQuery, parameters).catch(error => {
                    LogErrors.logError(error);
            });
            if(output.rowsAffected[0]>0){
                    finalResult.push(output.rowsAffected[0]);
            }else{
                throw new console.error('Unexpected error occurred while updating');
            }

        })
        );

  }

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

The functionality of the $.post function is not providing the accurate data in its return

Using $.post to transmit data to my main page from droppable elements is causing an issue. When I echo out the data, the toolbar is also being echoed out along with the fetched data. if (isset($_POST['data'])){ $data = $_POST['data']; ...

Angular and JS have differing opinions on how to determine if objects are equal

I am currently developing an application to showcase specific data using a grid and a data source. Let me present the issue first and then elaborate on the situation. $scope.onSelectRow = function (row, rowId) { var a = row; ...

If the width of the table is set to 100% in the CSS, the legend in the Flot chart will automatically shift to the

When the CSS for the table is set to { width:100%}, the Flot chart's legend moves to the left side. Is there any way to maintain the table { width:100%} while also preventing this shift, considering that the CSS is applied site-wide? Here is a jsfid ...

Vue | The module does not have a default export statement

I encountered an issue with Vue3, TypeScript, and Vue CLI where I received the following error message: Module '"c:/Users/USER/Documents/top-secret-project/src/components/Features/Features.vue"' has no default export. This error occurre ...

Attempting to update information in JSON using AJAX and PHP

I am attempting to update key values in a JSON object using PHP, AJAX, and JavaScript to display the new values. Here is an example of my JSON database that needs to be modified: "answer01count": "1", "answer02count": "2", "answer03count": " ...

Displaying separate items onto a webpage based on their unique identifiers

Currently, I am in the process of developing a JavaScript web application that retrieves input from a user (specifically the name of a music artist) and then produces a list of related artists along with their most popular songs, all thanks to information ...

"Even when hidden, an HTML Div element still occupies space on the

I encountered an issue with my tabbedPage setup. Even though I have hidden content, it still occupies space on the page. Here is the code snippet that I am using: let tabHeader = document.getElementsByClassName("tabbedpage-header")[0]; let tabIndicator = d ...

Switch out 2 Bootstrap columns for 2 concealed columns with just a click. Utilizing Rails 4 and Bootstrap

Using Twitter Bootstrap 3 for a column system showcasing four similar advertisements at the bottom of the page. Code Snippet: <div class="row similar"> <% @recomended_ads.each do |advertisement| %> <div class="col- ...

The use of SetState within useEffect is having an impact on the functionality of the select input

Every select menu includes an informative text displayed inside a box, similar to a tooltip. Users have the option to close these boxes by clicking the 'close button' or by clicking outside of them. The current solution successfully closes the b ...

It seems that there is a null value being returned in the midst of the

I have developed a model using express. While setting this in one function, it returns null in another function, forcing me to use return. What is the proper method to handle this situation? const Seat = function(seat) { this.seat = seat.seat; this. ...

Filtering d3 SVG based on JSON attribute using a dropdown menu

My data consists of nodes and links for a force directed graph, where nodes can have one, two, or three connections: {"nodes": [{"id": "Michael Scott", "numOfLinks": 1} ,{"id": "Jim Halpert", "numOfLinks": 1} ,{"id": "Pam Beasley", "nu ...

What is the process for retrieving the component along with the data?

As I work on compiling a list of div elements that require content from my firebase cloud storage, I find myself unsure about how to effectively run the code that retrieves data from firebase and returns it in the form of MyNotes. Consider the following: ...

Send a single piece of data using AJAX in Flask

I have a very basic HTML form containing only one <input type='text'> field for entering an email address. I am trying to send this value back to a Python script using AJAX, but I am having trouble receiving it on the other end. Is there a ...

Is there a way to display personalized messages in the console section when visitors access the developer tools on my website?

During a recent exploration of the dev tools on Reddit.com and Facebook.com, I noticed that both sites had custom messages specifically targeting developers who access the console. Reddit was actively recruiting developers through an ad, while Facebook had ...

Strategies for resolving duplicate jQuery code in my project

Trying to simplify my jQuery code that handles video selection and playback functionality. Users can click on a thumbnail or button to play a specific video, with the title of the video changing accordingly. Despite achieving the desired outcome, the cur ...

Freezing the website by setting async to false

I've been having issues with my website freezing when using async set to false. I need confirmation before executing the script. $.ajax({ type: "POST", url: url, data: form.serialize(), async: false, success: function(data) { ...

Ways to determine the presence of a value in an array using AngularJs

I'm currently working on looping through an array to verify the existence of email, phone, and alternate phone in a database. My challenge lies in finding a suitable function or workaround in AngularJS that allows me to iterate through the array with ...

Dynamically insert a new row into a table amidst existing rows

Once I had a table structured like this <table> <tbody> <tr id="tr_0" class="class_tr_0">...</tr> <tr id="tr_1" class="class_tr_1">...</tr> <tr id="tr_2" class="class_tr_2">...</tr&g ...

How to print a specific div from an HTML page with custom dimensions

I am looking for a solution to print just a specific div from a website with dimensions of 3"x5". Despite setting up the print button, the entire page continues to print every time. Is there a way to hide all non-div content in print preview? CSS .wholeb ...

Issue encountered when trying to add data into MySQL database

Having trouble inserting data into my MySQL database, even though I believe I'm doing it correctly. Does anyone know how to troubleshoot this issue or if I may have overlooked something? Everything seems to be working fine, but for some reason, it&apo ...