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

Encountered an error in Discord.js: Undefined properties unable to be read (execute)

Here is the code snippet from my main file: const { Client, IntentsBitField, Collection, intents, SlashCommandBuilder } = require('discord.js') const { TOKEN, PREFIX } = require('./config.json') const fs = require('fs'); const ...

Dynamically access nested objects by utilizing an array of strings as a pathway

Struggling to find a solution for accessing nested object properties dynamically? The property path needs to be represented as an array of strings. For example, to retrieve the label, use ['type', 'label'] I'm at a roadblock wit ...

Bootstrap not being recognized in AngularJS HTML

I've been working on learning AngularJS, but unfortunately I can't seem to get any Bootstrap themes to show up in my web application. Here is the HTML code for the header that I've been trying: <nav class="navbar navbar-default"> ...

Numerical values are not considered by the JavaScript table filter

I'm having trouble with dynamically filtering the content. It works fine for the first two columns, but not for the third one. Maybe I need some additional JavaScript? Here is the link to my snippet: `https://www.w3schools.com/code/tryit.asp?filen ...

Jquery Ajax is met with a 400 error indicating a BAD request

I've encountered an issue while trying to send data to my local DB server. Every time I attempt to send the data, I keep receiving a 400 Bad Request error. var studentEmail = "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail ...

Enhancing the mobile menu with a feature that allows users to easily close the

I am currently designing a mobile menu for a website that I created using Wordpress with the Divi Theme. When the user clicks on a "hamburger icon", it triggers a fullscreen menu to open: mobile menu If you tap on "Termine", it will reveal a submenu: mo ...

Encountering an error with the node module timestampnotes: 'command not recognized'

I am encountering an issue while trying to utilize a npm package called timestamp notes. After executing the following commands: $npm install timestampnotes $timestamp I receive the error message: timestamp:126: command not found: slk Subsequently, I ...

Is it possible to incorporate knockout.js within a Node.js environment by utilizing .fn extensions in custom modules?

I'm currently exploring the possibility of implementing the knockout.mapping.merge library in node.js, but I seem to be facing a challenge when it comes to extending ko objects within the module's scope. I am struggling to figure out how to exten ...

Having trouble getting an HTML form to work when making a PHP and Ajax request

I am trying to validate an HTML form using Ajax to prevent the browser from loading the page. Ideally, when a user enters their first name, it should display above the HTML form. However, I am encountering an issue where it is not showing up as expected... ...

How do you incorporate ScrollTop animations using @angular/animations?

I'm attempting to recreate the animation showcased on Material.io: https://i.stack.imgur.com/OUTdL.gif It's relatively easy to animate just the height when clicking on the first card in the example above. The challenge arises when you click on ...

Tips for creating dynamic alerts using mui v5 Snackbar

My goal is to call an API and perform several actions. After each action, I want to display the response in a Snackbar or alert. Despite iterating through the messages in a map, I'm only able to show the first response and none of the others. Here is ...

I am trying to access the serial number data from an array of objects in ReactJS. Can anyone guide me

Is there a way to extract data from an array of objects, such as getting the serial number in ReactJS? In my current code snippet, I have an array called "number" with values [1, 2, 3]. My goal is to retrieve and display these numbers as a string like th ...

What is the best way to handle promises within the context of updating state in React

Recently, I've been working on a React code snippet focused on creating a text input field. onChangeDestination(url, index) { this.setState(prevState => { const rules = [...prevState.rules]; rules[index] = { ...rules[index], url}; ...

jQuery blueimp File Uploader: Transferring multiple files to the server on Internet Explorer

After customizing the demo for my Rails application, I encountered an issue with the plugin in Internet Explorer. While it works smoothly on Chrome and Firefox, in IE (all versions) it fails to upload all but one file when multiple files are selected, and ...

When the menu is selected, I would like for this div to both appear on the screen and slide

I need this div to be visible and move up when a menu item is selected. Can anyone provide a solution for this? Thank you in advance. <html><head> <script type="text/javascript"> <!-- var divobject = null; function init(id){ div ...

Encountering an issue: ReferenceError: regeneratorRuntime is not defined when implementing react-speech-recognition in nextjs13

Encountering the errorReferenceError: regeneratorRuntime is not defined in my NextJS project I'm currently using Redux toolkit. Link to my project. Please note that the code triggering the error can be found under the nextjsfrontend branch. I' ...

Unable to retrieve content using the query.ID in Next.js

I'm trying to figure out what is causing the issue in this code, but I can't seem to resolve it. My goal is to use the query.id inside getInitialProps to fetch some content. The fetching process works fine, but when an error occurs, I receive thi ...

The redirection did not occur as no authorization token was detected

I have two Nodejs applications, one for the front-end and the other for the back-end. The back-end app is secured with token access using express-jwt and jsonwebtoken middlewares. My issue is as follows: when I make a request from the front-end to the bac ...

Using Node.js to parse JSON data fetched from the web

My current challenge involves retrieving and parsing JSON from a web API (https://api.coinmarketcap.com/v1/ticker/?limit=3) in order to extract the name and price_usd fields. For example: [ { ... sample data provided ... } ] The code snippet I am wo ...

JavaScript code to alter the timeout duration for image changes: Update

I am working on a fun project that involves alternating between two images, one green and the other black. Here is the code snippet: <script> var switchImage = 1; var delayTime = 500; switchImages() function switchImages() { if (switchImage == 1) ...