Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Wait for a fetch function to finish

I’m trying to use the curseforge API in a project using fetch in nodejs18, this is the code I’m using:

ids = ["238222","60089","556448"]

const headers = {
  'Accept':'application/json',
  'x-api-key':'API KEY'
};

function getMods(id){
  fetch("https://api.curseforge.com" + '/v1/mods/' + id,
  {
    method: 'GET',

    headers: headers
  })
  .then(function(res) {
      return res.json();
  }).then(function(body) {
      console.log(body.data.name);
  });
}

ids.forEach(element => {
  getMods(element)
});

//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------

console.log("download finished")

With that code what you want to be printed in the terminal is:

Alex's Delight
Mouse Tweaks
Just Enough Items (JEI)
download finished

but when running the program I get this in the terminal:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

download finished
Alex's Delight
Mouse Tweaks
Just Enough Items (JEI)

This happens because the fetch function is asynchronous, I have tried all the methods to solve this problem but no solution is what I want.

What I want is for the program to wait for the foreach and fetch to finish to continue executing.

>Solution :

Here’s roughly how it’s done:

const ids = ["238222","60089","556448"]

const headers = {
  'Accept':'application/json',
  'x-api-key':'API KEY'
};

async function getMods(id){

  const res = await fetch("https://api.curseforge.com" + '/v1/mods/' + id, {
    method: 'GET',
    headers,
  })
  const body = await res.json();
  console.log(body.data.name);
}

async function run() {

  for(const element of ids) {
    await getMods(element);
  }
  console.log("download finished")

}

run();

If you want to download the mods in parallel instead of one at a time, this is how the run() function should look like instead:

async function run() {

  await Promise.all(
    ids.map(element => getMods(element))
  );
  console.log("download finished")

}

If you use ESM, you can avoid the ‘run’ function and just use await at the top-level. To easily take advantage of that with node, just save your file with the .mjs extension.

Then the final code might look like this:

const ids = ["238222","60089","556448"]

const headers = {
  'Accept':'application/json',
  'x-api-key':'API KEY'
};

async function getMods(id){

  const res = await fetch("https://api.curseforge.com" + '/v1/mods/' + id, {
    method: 'GET',
    headers,
  })
  const body = await res.json();
  console.log(body.data.name);
}


await Promise.all(
  ids.map(element => getMods(element))
);
console.log("download finished")
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading