Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Web Development
  3. JavaScript
  4. wait for fetch to finish within a for each loop

wait for fetch to finish within a for each loop

Scheduled Pinned Locked Moved JavaScript
javascriptjsonsysadminregextutorial
4 Posts 3 Posters 3 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jkirkerx
    wrote on last edited by
    #1

    I thought this would be easy, but didn't consider my for each loop just running and calling fetch really fast, when I need to call fetch one at a time until it finishes. Or maybe not if I consider the web server being able to process that many fetches, say 30 to 60, but I would hate to load up the web server with that many jobs. I have this long process, that may take 2 or 3 minutes each, and didn't want to send a large payload of jobs to the API, so I broke the payload down into individual jobs to send to the API one at a time. I extracted the payload and ran each payload in a loop. I'm not sure if I need to tell the loop to wait, or tell fetch to wait. I've never done this before in JavaScript and I'm not sure how to approach this. Tried a few things, but I probably need to write test code that reflects the principals first and confirm that it works, and then adjust my code. Everything I found on the Internet didn't really match what I wanted to do. I pasted my function so you can see what I'm trying to achieve. I've worked with promise before in Angular, waiting for google API to validate my google credentials but that was a single transaction.

    async function runProjectUpdateCostAsync() {

    const vendorId = document.getElementById('updateProjectCost\_vendorId').value;
    const bodyPayload = JSON.parse(document.getElementById('updateProjectCost\_jsonPayload').value);
    const priceLists = JSON.parse(bodyPayload.priceLists);
    
    // Program the Api Url
    let apiUri = document.getElementById('updateProjectCost\_apiUri').value;
    apiUri += '?updateProjectCost=true';
    
    // Were now looping through priceList to shorten the time
    let promise = Promise.resolve();
    for await (const priceList of priceLists) {
    
        const statusElement = document.getElementById(priceList.statusElement);
        const img = new Image();
        img.src = '/assets/images/Gear-0.2s-32px.gif';
        img.alt = 'wait';
        statusElement.innerHTML = '';
        statusElement.appendChild(img);
    
        const newBodyPayload = JSON.stringify({
            "vendorId": vendorId,
            "priceLists": "\[" + JSON.stringify(priceList) + "\]"
        });
    
        const span = document.createElement('span');
        span.classList.add('font-weight-bold');
        span.classList.add('mx-2');
    
        promise = promise.then(fetch(apiUri, {
            method: 'POST',
            body: newBodyPayload,
            headers: {'Content-type': 'application/text; charset=utf-8'}
        })
    
    Richard DeemingR 1 Reply Last reply
    0
    • J jkirkerx

      I thought this would be easy, but didn't consider my for each loop just running and calling fetch really fast, when I need to call fetch one at a time until it finishes. Or maybe not if I consider the web server being able to process that many fetches, say 30 to 60, but I would hate to load up the web server with that many jobs. I have this long process, that may take 2 or 3 minutes each, and didn't want to send a large payload of jobs to the API, so I broke the payload down into individual jobs to send to the API one at a time. I extracted the payload and ran each payload in a loop. I'm not sure if I need to tell the loop to wait, or tell fetch to wait. I've never done this before in JavaScript and I'm not sure how to approach this. Tried a few things, but I probably need to write test code that reflects the principals first and confirm that it works, and then adjust my code. Everything I found on the Internet didn't really match what I wanted to do. I pasted my function so you can see what I'm trying to achieve. I've worked with promise before in Angular, waiting for google API to validate my google credentials but that was a single transaction.

      async function runProjectUpdateCostAsync() {

      const vendorId = document.getElementById('updateProjectCost\_vendorId').value;
      const bodyPayload = JSON.parse(document.getElementById('updateProjectCost\_jsonPayload').value);
      const priceLists = JSON.parse(bodyPayload.priceLists);
      
      // Program the Api Url
      let apiUri = document.getElementById('updateProjectCost\_apiUri').value;
      apiUri += '?updateProjectCost=true';
      
      // Were now looping through priceList to shorten the time
      let promise = Promise.resolve();
      for await (const priceList of priceLists) {
      
          const statusElement = document.getElementById(priceList.statusElement);
          const img = new Image();
          img.src = '/assets/images/Gear-0.2s-32px.gif';
          img.alt = 'wait';
          statusElement.innerHTML = '';
          statusElement.appendChild(img);
      
          const newBodyPayload = JSON.stringify({
              "vendorId": vendorId,
              "priceLists": "\[" + JSON.stringify(priceList) + "\]"
          });
      
          const span = document.createElement('span');
          span.classList.add('font-weight-bold');
          span.classList.add('mx-2');
      
          promise = promise.then(fetch(apiUri, {
              method: 'POST',
              body: newBodyPayload,
              headers: {'Content-type': 'application/text; charset=utf-8'}
          })
      
      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      The Promise.resolve() method[^] returns an already-resolved promise object. I don't understand why you think you need that? Using .then in an async method is a definite code-smell. Why aren't you using await instead?

      const response = await fetch(apiUrl, { ... });
      if (!response.ok){
      span.classList.add('text-danger');
      span.innerHTML = 'Failed';
      statusElement.innerHTML = '';
      statusElement.appendChild(span);

      const errorMessage = await response.text();
      console.error("runProjectUpdateCost Error: ", response.status, response.statusText, errorMessage);
      

      } else {
      const data = await response.json();
      span.classList.add('text-success');
      span.innerHTML = 'Success';
      statusElement.innerHTML = '';
      statusElement.appendChild(span);
      }

      Also, priceLists doesn't look like an async iterable, so I don't think you need the for await (...) syntax: for await...of - JavaScript | MDN[^]


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      J 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        The Promise.resolve() method[^] returns an already-resolved promise object. I don't understand why you think you need that? Using .then in an async method is a definite code-smell. Why aren't you using await instead?

        const response = await fetch(apiUrl, { ... });
        if (!response.ok){
        span.classList.add('text-danger');
        span.innerHTML = 'Failed';
        statusElement.innerHTML = '';
        statusElement.appendChild(span);

        const errorMessage = await response.text();
        console.error("runProjectUpdateCost Error: ", response.status, response.statusText, errorMessage);
        

        } else {
        const data = await response.json();
        span.classList.add('text-success');
        span.innerHTML = 'Success';
        statusElement.innerHTML = '';
        statusElement.appendChild(span);
        }

        Also, priceLists doesn't look like an async iterable, so I don't think you need the for await (...) syntax: for await...of - JavaScript | MDN[^]


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        J Offline
        J Offline
        jkirkerx
        wrote on last edited by
        #3

        It had been awhile since I had written a promise, and I knew that fetch is a promise when called once. I can see that I just need to wait for fetch and just let the loop run which is what I was hoping would be the proper way to handle this. So wait for Fetch to return it's result, and based on the external result then trigger my UI decorations. The promise.resolve came from just being brain dead, after spending time trying to figure out why I can JSON.parse my JSON, yet not get an object deeper inside what I just parsed, thus the double JSON.parse on priceLists. Thanks Richard!

        If it ain't broke don't fix it Discover my world at jkirkerx.com

        A 1 Reply Last reply
        0
        • J jkirkerx

          It had been awhile since I had written a promise, and I knew that fetch is a promise when called once. I can see that I just need to wait for fetch and just let the loop run which is what I was hoping would be the proper way to handle this. So wait for Fetch to return it's result, and based on the external result then trigger my UI decorations. The promise.resolve came from just being brain dead, after spending time trying to figure out why I can JSON.parse my JSON, yet not get an object deeper inside what I just parsed, thus the double JSON.parse on priceLists. Thanks Richard!

          If it ain't broke don't fix it Discover my world at jkirkerx.com

          A Offline
          A Offline
          albenpure
          wrote on last edited by
          #4

          https://www.albenpure.com/

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups