Exploring the values of a JavaScript promise while iterating through a for loop

I find myself wandering in the land of possibilities and would greatly appreciate some direction. After spending 2-3 hours scouring through countless SO questions and documentation related to my current predicament, I still seem to be missing the mark.

Overview

The code snippet provided below is designed to work with an Object type (resources) by extracting specific values and using them to calculate distance and duration using GoogleMaps Distance Matrix. The googleRequest() function returns a promise with two values (distance and duration).

My goal is to retrieve these values within the for loop, perform pushToRows(), and ultimately return an array called final_rows.

Problem

Upon inspection, it appears that the final_rows array displays UNDEFINED for both duration and distance keys in every row. This could be attributed to improper access of values from dist_dur. Any assistance in resolving this matter would be greatly appreciated. Thank you.

Code

final_rows = []

    function getDistTime(resources){
        for (var i = 0; i < resources.data.length; i++) {
            var origin1 = $("#citystate").val();
            var destinationA = resources.data[i]['DEMOBILIZATION CITY'] + ',' + resources.data[i]['DEMOBILIZATION STATE'];
            var dist_time_data = googleRequest(origin1, destinationA).then((values) => {
                return values
            })
            pushToRows(resources.data[i], dist_time_data)
        }
        // console.log(final_rows)

    } 

    function pushToRows(resources, dist_dur){
        resources["DISTANCE_MI"] = dist_dur[0];
        resources["ACTUAL_DUR_HR"] = dist_dur[1];
        resources["FINANCE_DUR_HR"] = (dist_dur[0] / 45.0).toFixed(2)
        final_rows.push(resources)   
    }

Answer №1

If you want to optimize your code, consider storing promises in an array within a for loop and then waiting for them all to resolve using Promise.all. This will allow you to parallelize requests to the Google Distance API.

    function getDistTime(resources){
        const promiseArr = [];
        for (var i = 0; i < resources.data.length; i++) {
            var origin1 = $("#citystate").val();
            var destinationA = resources.data[i]['DEMOBILIZATION CITY'] + ',' + resources.data[i]['DEMOBILIZATION STATE'];
            promiseArr.push(googleRequest(origin1, destinationA));
            
        }
        // If you're not waiting for promises to be resolved, data may be updated later on
        return Promise.all(promiseArr)
            .then((resultsArr) => {
                resultsArr.forEach((result, i) => pushToRows(resources.data[i], result));
            })

    } 

    function pushToRows(resources, dist_dur){
        resources["DISTANCE_MI"] = dist_dur[0];
        resources["ACTUAL_DUR_HR"] = dist_dur[1];
        resources["FINANCE_DUR_HR"] = (dist_dur[0] / 45.0).toFixed(2)
        final_rows.push(resources)   
    }

To simplify your code and make it more readable, I suggest using async-await, which is syntactic sugar for promises and can help eliminate the complications associated with promise chaining.

Answer №2

By moving your pushToRows() function inside the block where you return values, you will be able to access that data.

googleRequest(origin1, destinationA).then((values) => {
    pushToRows(resources.data[i], values);
});

If the promise hasn't resolved yet, dist_time_data will still be undefined.

An alternative approach is to use Promise.all(), which allows you to pass an array of promises and waits until all of them are complete:

function getDistTime(resources){
    const promises = [];

    for (var i = 0; i < resources.data.length; i++) {
        var origin1 = $("#citystate").val();
        var destinationA = resources.data[i]['DEMOBILIZATION CITY'] + ',' + resources.data[i]['DEMOBILIZATION STATE'];
        promises.push(googleRequest(origin1, destinationA));
    }

    return Promise.all(promises).then((results) => {
        return results.map((result, i) => {
            return {
                ...resources.data[i],
                DISTANCE_MI: result[0],
                ACTUAL_DUR_HR: result[1],
                FINANCE_DUR_HR: (result[0] / 45.0).toFixed(2)
            };
        });
    });
}

getDistTime(resources).then(result => {
    // The variable "result" now holds the final_rows
});

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

Automatically reduce the size of Java Script files and CSS files with compression

I'm currently working with Google App Engine and JQuery. I'm looking for a solution that can automatically compress my JavaScript and CSS files when deploying them to the GAE server. It's quite cumbersome to manually compress all the files e ...

<Select> Placeholder customization

For my react project, I am utilizing material-Ui and I am looking to have a placeholder that stands out by having grey text instead of black when compared to the selected item. <Select name="answer" value={values.answer} onChange={handleChange} onBlur= ...

Horizontal scrolling alone is proving to be ineffective

My current HTML code includes a table that is integrated with PHP Laravel. The data is being pulled from Admin.php to populate the table, resulting in it being wider than the screen window. To address this, I added a horizontal scroll bar for navigation pu ...

Element Proxy

I decided to experiment and see how a library interacts with a video element that I pass to it. So, I tried the following code: const videoElement = new Proxy(document.querySelector('video'), { get(target, key) { const name = typeof ...

What sets these async method declarations apart?

What goes on behind the scenes? const facade = { // A: doSomething: async () => await delegatedFunction(), // B: doSomething: async () => delegatedFunction(), // C: doSomething: () => delegatedFunction(), // D: do ...

"The Ajax POST request to MyUrl returned a 404 error, indicating that the resource

While working on my Grails code, I encountered an error when the Ajax function received a response from the controller action. The parameters are being passed successfully by the Ajax function, and the controller function is executed. However, upon return ...

Colorbox scalePhotos function malfunctioning

The scalePhotos option in Colorbox does not seem to be working correctly for me. I have tried various methods to set it, including initializing Colorbox using the following code snippet right before the closing </body> tag in my HTML: jQuery('a ...

Creating a text file in Node.js using nodepad formatting

Could anyone assist me with formatting text in a Node.js file to be written to Notepad? Here's the code I'm currently using: const fs = require('fs'); fs.writeFile('write.txt', '', err => {}); var text = [ ...

How to resolve: Preventing Ajax - Post request from executing repetitively

I am facing an issue with a table that is formatted using the Datatables script. There is a column in the table which contains icons for actions. When a user clicks on an icon, a modal is loaded and its content is fetched using the POST method. The modal ...

I am struggling to render the pages and components in React while using BrowserRouter

Below is the code snippet for App.js and Home.js that I'm working on. My aim is to showcase the Home.js component in the browser. App.js import "./App.css"; import { Route, BrowserRouter } from "react-router-dom"; import Home from ...

Why is it that the HttpClient constructor in Angular doesn't require parameters when instantiated through the constructor of another class, but does when instantiated via the 'new' keyword?

I am trying to create a static method for instantiating an object of a class, but I have encountered a problem. import { HttpClient } from '@angular/common/http'; export MyClass { // Case 1 public static init(): MyClass { return this(new ...

Minimize the number of HTTP requests by including CSS and JS files in PHP

I've been considering a method to reduce the number of HTTP requests made when loading a page by minimizing the amount of downloaded files, while still keeping separate files on the server. The thought process is as follows: <!DOCTYPE html> &l ...

Compatibility issues between jQuery and AngularJS are causing problems

Currently, I am facing a compatibility issue between RequireJS and Angular in my setup. Everything functions without any problems when using jQuery version 1.7.2. However, I wanted to upgrade to jQuery 1.8.1 along with jQuery UI, but unfortunately, my Angu ...

Transforming an Image URL into base64 format using Angular

I'm currently facing difficulty when attempting to convert a specified image URL into base64. In my scenario, I have a string that represents the image's path. var imgUrl = `./assets/logoEmpresas/${empresa.logoUrl}` Is there a way to directly co ...

My toggleclass function seems to be malfunctioning

I am encountering a strange issue with my jQuery script. It seems to work initially when I toggle between classes, but then requires an extra click every time I want to repeat the process. The classes switch as expected at first, but subsequent toggles req ...

What is the best way to deliver static HTML files in Nest.js?

I am encountering an issue with loading JS files from a static /dist folder located outside of my Nest project. While the index.html file loads successfully, any JS file results in a 404 error. In another Node/Express.js project, I am able to serve these ...

What is the most effective way to incorporate the DOMContentloaded event listener into the document using nextJS?

I am working on integrating an HTML code snippet into my Next.js project. The snippet includes an external script with a createButton function. <div id="examplebtn"></div> <script type="text/javascript"> //<![ ...

Issue: Trouble with ajax form functionality

I'm a beginner in ajax, js, and php. Recently, I set up a simple contact form. <form id="contact-form" method="post" action="process.php" role="form"> <div class="messages"></div> <div class="form-group"> <l ...

acquiring data via fetch (transferring information from javascript to php file)

I'm completely new to using fetch and not familiar with Ajax. Currently, I am attempting to transfer data from a JavaScript file (node.js server) to a PHP file (Apache server). The data being sent consists of 2 JSON values labeled as "a" and "b". T ...

Calculating Time Difference in JavaScript Without Utilizing moment.js Library

I have two timestamps that I need to calculate the difference for. var startTimestamp = 1488021704531; var endTimestamp = 1488022516572; I am looking to find the time difference between these two timestamps in hours and minutes using JavaScript, without ...