Using the for loop to asynchronously fetch data and access the finished result variable

Exploring the world of asynchronous JavaScript, I find myself pondering a question: how can I ensure that my code only starts working on a created array once all queries are completed? My current approach involves fetching pages in a for loop. Here's a snippet of my code:

var allOrgReposData = [];
var repoContributorsUrls = [];
for (var i=1; i <= orgPageIterations; i++) {
  var orgReposUrl = 'https://api.github.com/orgs/angular/repos?page='+i;
  fetch(orgReposUrl)
  .then(response => response.json())
  .then(orgReposData => {
    allOrgReposData = allOrgReposData.concat(orgReposData);
    console.log(allOrgReposData);
   })
}  

In this code snippet, you'll notice that the allOrgReposData array is being populated within the for loop. However, any operations I try to perform on this array end up being multiplied with each iteration, leading to unexpected results. For example, with 30 items per page, I see calculations like 30; 60; 90; 120; 150; 171 equating to 621 instead of the expected 171.

Is there a way to pause execution until all data is fetched and avoid this "multiplication" effect?

Warm regards!

Answer №1

One way to handle multiple promises is using Promise.all, which will ensure all promises are completed before proceeding:

var allOrgReposData = [];
var repoContributorsUrls = [];

var promises = [];
let orgPageIterations = 1;

for (var i = 1; i <= orgPageIterations; i++) {
  let orgReposUrl = 'https://api.github.com/orgs/angular/repos?page=' + i;
  promises.push(fetch(orgReposUrl).then(response => response.json()));
}

Promise.all(promises)
  .then(data => {
    allOrgReposData = data;
    console.log(allOrgReposData);
  })
  .catch(err => console.error(err));

It's worth noting that I've made the change from var orgReposUrl to let orgReposUrl for better block scoping.

Answer №2

To keep a record of the number of calls made, you can use a variable:

var allOrgReposData = [];
var repoContributorsUrls = [];
var callCounter = 1; //Variable to track ajax calls
for (var i=1; i <= orgPageIterations; i++) {
  var orgReposUrl = 'https://api.github.com/orgs/angular/repos?page='+i;
  fetch(orgReposUrl)
  .then(response => response.json())
  .then(orgReposData => {
    allOrgReposData = allOrgReposData.concat(orgReposData);
    console.log(allOrgReposData);
    callCounter++; //Increment counter for each call

    if(callCounter == orgPageIterations){ //If all calls have been completed, proceed
      //DO YOUR TASK HERE
    }
   })
}  

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

Show popup window during servlet processing

I'm attempting to display a modal box in a Java servlet with the message "Please wait while your request is processed". I understand that I can make an AJAX call and manage the modal in the front-end code. Currently, I trigger the servlet when the us ...

How to fetch images from a database in CodeIgniter by utilizing JSON and AJAX functions?

Trying to retrieve an image using ajax/json format for the first time, all variables are displaying except the image. The name of the image is visible when inspecting the element in the browser and it is saving correctly into the image folder. I need help ...

Guide on how to submit an image along with text using AJAX, PHP, and HTML

Hey there! I'm currently working on a project where I need to upload an image with comments added into a database using a combination of PHP, AJAX, and HTML. Let me show you the HTML part first: <form name="form1" enctype="multipart/form-data" ac ...

Overlay a small image on top of a larger background image using canvas, then merge them into a single set of pixel

Is there a way to combine a smaller image with a larger background image on one canvas while allowing the smaller image to move around? I'll need to save the original background pixel data so that each frame can be redrawn with the overlay in its upda ...

Cipher/decipher URL Redirect Parameter

While sending the return URL as a query string parameter, it looks like this: http://localhost:50316/TripNestFinal/Login.aspx?ReturnUrl=~/Account/AccountSettings.aspx However, I am seeking a way to encode ~/Account/AccountSettings.aspx in a manner that wi ...

Guide to setting up a datePicker in a cellEditorSelector

In my grid, I want to have different editors for different rows within the same column. The ag-Grid documentation provides information on how to achieve this using colDef.cellEditorSelector as a function: link I have successfully created unique editors fo ...

How can I create multiple divs that look alike?

I've taken on the challenge of developing our own interpretation of Conway's "Game of Life" for a project. To represent my 20x20 grid, I decided to create nested divs - the whole grid is one div, each row is a div, and every cell within that is a ...

I encounter an error while attempting to deserialize a JSON string, making it impossible to

I am encountering an issue with the following code snippet: string downloadString = client.DownloadString(serviceurl); List<Player> myDeserializedObjList = (List<Player>)JsonConvert.DeserializeObject(downloadString, typeof(List<Player>)) ...

Experience a dynamic D3 geometric zoom effect when there is no SVG element directly underneath the cursor

Currently, I am working on incorporating a geometric zoom feature into my project. You can see an example of what I'm trying to achieve in this demo. One issue I've encountered is that when the cursor hovers over a white area outside of the gree ...

Why won't my JavaScript addEventListener activate on form submission?

I have a basic question as a beginner in JavaScript. I am facing some challenges with my first task involving JavaScript. I decided to learn JS by creating a TODO List, but I am stuck right at the beginning. The event listener that should respond when the ...

What is the best way to transfer information from the window method to the data function in a Vue.js application?

Is there a way to transfer information from the window method to the data function in a vuejs component? Take a look at my window method: window.authenticate = function(pid, receiptKey) { console.log("Authentication"); console.log(this) localStorag ...

Is there a way to modify the appearance of a particular element in ng-repeat?

On my website, I am using ng-repeat to display various dish postings. I want to trigger a modal to open when I click on a dish, showing the specific data for that dish. To achieve this, I'm assigning each dish a modal div with a unique ID (dish-$index ...

Methods for delivering static resources on multiple routes in Express JS

Is there a way to effectively serve static resources for all routes in Express JS? I attempted to serve files with static resources using the following code snippet: app.use(Express.static(`${this.PATH}`)); app.use(Cors()); app.use(Express.json()); app.g ...

Error in Babel-Loader when executing npm run build

Not being a webpack expert, I decided to upgrade from V3 to V4. After fixing the depreciation errors in my webpack config, I hit a roadblock with a syntax error from babel-loader: Module build failed (from ./node_modules/babel-loader/lib/index.js): ...

Upon clicking, the input texts revert to their original default values

I have a form below that is working as intended, except for one issue. When I click the 'Add' link, the texts in all the textboxes revert to their default values, as shown in the images. How can I resolve this problem? Thank you. before click: ...

What could be causing the block to fail in the event of an AJAX request?

I have encountered an issue with my PHP file and AJAX setup. The if block in my code is working properly, but the else block seems to be not functioning as expected. Even after changing the condition from data!= null to data== null, the problem persists wh ...

Avoid running multiple YouTube views simultaneously within an AngularJS application

Currently, I have an Angularjs application that displays a list of Youtube videos utilizing the videogular node module. An issue has arisen where users can play multiple Youtube videos simultaneously, leading to potential violations of Youtube's poli ...

Error encountered when attempting to retrieve HTML content from localhost using AJAX

Attempting to insert HTML code into a div element using ajax, similar to how it's done with an iframe. Testing this out locally first to avoid Same Origin Policy complications. The web application is currently hosted on a wamp server. There are two ...

executing npm tasks concurrently

Trying to demonstrate running npm tasks in parallel is my current task. I should be able to achieve this using "&" for parallel and "&&" for series. { "name": "npm", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "co ...

Having trouble finishing the npm installation process

Having trouble with completing 'npm install'. Can someone please assist me?</p> <pre><code>Encountering a warning about an old lockfile while running npm install. The package-lock.json file was created with an outdated version o ...