Leveraging the power of the fetch function within a JavaScript for loop

As a beginner in JavaScript, I wrote some code to fetch URLs using the fetch API. However, I encountered an issue with my code where it says Functions declared within the loop are referencing an outer scoped variable. I understand that this is because of the outer scope of the obj variable, but I'm unsure how to fix it. Please assist me. Here's the code snippet:

var obj = [
  {"Id":"10101","descr":"server1.com"},
  {"Id":"10102","descr":"server2.com"},
  {"Id":"10103","descr":"server3.com"},
  {"Id":"10104","descr":"server4.com"},
  {"Id":"10105","descr":"server5.com"},
  {"Id":"10106","descr":"server6.com"}, 
  {"Id":"10107","descr":"server7.com"}
];

var temp = [];
for (var i = 0; i < obj.length; i++){      
  
  var id = obj[i].Id;      
  fetch('https://abced.com/api/'+id+'/value', {
    method : "GET",
    headers: { "Authorization": "xyz" }
  })
    .then(res => res.json())
    .then(data => { 
      var stats = data.status;          
      if (stats != "OK") {
        temp.push({ Id: obj[i].Id, descr: obj[i].descr, value:"ERROR" });
      }
      console.log(temp);
    })
    .catch(x => console.log("fail:", x))

}

The expected output should display as follows: (values of Id and descr will depend on the if statement in the code)

[{"Id": "10101","descr": "server1.com","status": "ERROR"},
{"Id": "10103","descr": "server3.com","status": "ERROR"},
{"Id": "10104","descr": "server4.com","status": "ERROR"}]

Answer №1

Using the syntax of async...await is recommended as it is much more readable compared to using numerous .then() handlers.

In this scenario, a for .. of loop is utilized to go through each Id and descr value in the obj array, executing the relevant fetch() call for each one.

The result of each fetch call is awaited, followed by a status check. If the status is not 'OK', the information is added to the results array.

var obj = [
  {"Id":"10101","descr":"server1.com"},
  {"Id":"10102","descr":"server2.com"},
  {"Id":"10103","descr":"server3.com"},
  {"Id":"10104","descr":"server4.com"},
  {"Id":"10105","descr":"server5.com"},
  {"Id":"10106","descr":"server6.com"}, 
  {"Id":"10107","descr":"server7.com"}
];

async function getResults() {
    const results = [];
    for(let { Id, descr} of obj) {
        const data = await fetch('https://abced.com/api/' + Id + '/value', {
          method : "GET",
          headers: { "Authorization": "xyz" }
        }).then(res => res.json());
        if (data.status !== 'OK') {
            results.push({ Id, descr, value: 'ERROR' })
        }
    }
    return results;
}

async function test() { 
    const results = await getResults();
    console.log('Results:', results)
}

test();

The following code snippet demonstrates a mock of fetch, illustrating what you can expect.

For ids 10101, 10103, and 10104, fetchMock returns a status of 'BAD', while for all other ids it returns 'OK'.

// For testing only, replace with fetch when appropriate...
function fetchMock(url) {
    let id = url.split('/')[4];
    if ([10101, 10103, 10104].includes(+id)) {
        return Promise.resolve({ json() { return Promise.resolve({ status: 'BAD'})}})
    } else {
        return Promise.resolve({ json() { return Promise.resolve({ status: 'OK'})}})
    }
}

var obj = [
  {"Id":"10101","descr":"server1.com"},
  {"Id":"10102","descr":"server2.com"},
  {"Id":"10103","descr":"server3.com"},
  {"Id":"10104","descr":"server4.com"},
  {"Id":"10105","descr":"server5.com"},
  {"Id":"10106","descr":"server6.com"}, 
  {"Id":"10107","descr":"server7.com"}
];

async function getResults() {
    const results = [];
    for(let { Id, descr} of obj) {
        const data = await fetchMock('https://abced.com/api/' + Id + '/value', {
          method : "GET",
          headers: { "Authorization": "xyz" }
        }).then(res => res.json());
        if (data.status !== 'OK') {
            results.push({ Id, descr, value: 'ERROR' })
        }
    }
    return results;
}

async function test() { 
    const results = await getResults();
    console.log('Results:', results)
}

test()
.as-console-wrapper { max-height: 100% !important; }

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

Transforming control of execution seamlessly between two interactive functions in nodejs

Two functions are used to take input from the CLI using process.stdin. The issue arises when one function is done taking input, as a similar function is called. However, while the control shifts to the second function, the first function continues executin ...

Scrolling the inner div with the main scrollbar before navigating through the rest of the page

In my hero div, I have a container div called right-col that contains two inner divs. These inner divs are sticky, creating the effect of cards sliding up when the container div is scrolled. This is the HTML structure: <!DOCTYPE html> <html lang= ...

Is there an issue with this particular jQuery if condition?

This page aims to display various options based on the selection made in the dropdown. The toggle functionality is currently working correctly without the need for an if statement. How do I modify the if statement to perform the accurate comparison? < ...

Replace particular letters within the text with designated spans

Suppose I have this specific HTML code snippet: <div class="answers"> He<b>y</b> <span class='doesntmatter'>eve</span>ryone </div> Additionally, imagine I possess the subsequent array: ['correct' ...

Issue with HTML5 Video Play on Hover Functionality Ceases to Work Upon Loading Dynamic Content

I recently implemented a feature on my WordPress site that allows videos to start playing when the mouse hovers over their thumbnails and pause when it leaves. However, I encountered an issue where this function works perfectly upon initial page load but f ...

Sending data with React using POST request

Currently in my React application, I have a form that includes fields for username and password (with plans to add "confirm password" as well). When submitting the form, I need it to send JSON data containing the email and password in its body. The passwo ...

Maintain original pitch of HTML video content (preservesPitch, mozPreservesPitch, webkitPreservesPitch)

I am attempting to turn off the preservesPitch feature on a video element that is playing in slow motion by adjusting the video's playbackRate. In Chrome, video.webkitPreservesPitch is not defined, and changing it to false or true doesn't affect ...

Controlled Checkbox Component in React

I'm really struggling with this. While I can easily work with select drop downs and text fields, I just can't seem to get checkboxes to function properly in a controlled manner. I want them to 'toggle' and respond to events in a parent ...

Update the chosen option in a dropdown list with jQuery and javascript

I need to set the value of a column in a repeater so that once it's assigned, the column will display the current selection from the dropdown. I have the correct value to assign in $('#myname_' + rowIndex).text(), but when I try to assign t ...

Timing of JQuery FadeOut is incorrect

Here is some code I am working with: $(document).ready(function () { $("#full-btns").children().delay(4000).fadeOut("slow"); $('#full-btns').hover(function() { $('#full-btns').children().stop().animate({opacity:'100'} ...

Communication between Nodemailer and Mailgun

I keep encountering an authentication issue while trying to use Nodemailer with Mailgun. I followed the Nodemailer documentation which states compatibility with Mailgun SMTP, but unfortunately, I am consistently facing this error when executing my applicat ...

Adjust the date and time from an XML file to the local date and time using JavaScript or JQuery

Upon checking the XML tag data retrieved from the open-weather API for Melbourne, I noticed that the sunrise is marked at 19:00 hours which seems incorrect. It appears that this discrepancy might be due to a conversion error as the API might be using UTC t ...

What is the most effective method for incorporating multi-line breadcrumb links in a React application?

I am currently working on implementing a multiline breadcrumb link feature for mobile and tablet devices. As users navigate through multiple folders, I need to handle scenarios where the number of links exceeds the maximum allowed in the breadcrumb contain ...

Leveraging the capabilities of the Freshdesk API

Has anyone had any experience utilizing the FRESHDESK API specifically for creating tickets? The documentation states the following: Request URL: domain_URL/helpdesk/tickets.xml Request method: POST <helpdesk_ticket> <description>Disk fai ...

Adding a Sequence of Class Names to <li> Elements with JavaScript

How can you easily generate sequential class names in a for loop? ...

Solution for unresolvable Ajax token error

I am encountering an error after using setTimeout and receiving an unexpected token. I was attempting to handle errors in my ajax request by displaying a message if there is one, or reloading the webpage after a few seconds. function submit ...

Is it possible to rotate the caret in the dropdown 180 degrees using only CSS?

Is there a way to achieve a 180° rotation of the caret in a dropdown menu upon clicking it, creating the illusion of an animation? I would prefer to accomplish this using CSS only, without the need for JavaScript, but I am open to any suggestions. .se ...

Update an array of objects by incorporating additional properties from another array, even if the two arrays are of different lengths. When the iteration of the array is complete, it should

Is there a way to merge two arrays of objects with different keys? I want to combine the keys of the second array with those of the first one. How can I accomplish this task? $scope.links = [ { name: 'JRD', status: 'active ...

The component is unable to access VueJS references

Below is a simplified version of the code I am working with: <html> <head> <script src="file:///D:/OtherWork/javascript/vue/vue.js"></script> </head> <body> <div id="app"> & ...

Refreshing the page reveals the complete local storage object

I've successfully created a todo list using Vanilla Javascript along with local storage. The todo list includes the following key-value pairs: key: todolist value: [[\"id:0\",\"title:buy groceries\",\"done:false\"], [&b ...