What is the best way to create a seamless Asynchronous loop?

Adhering to the traditional REST standards, I have divided my resources into separate endpoints and calls. The primary focus here revolves around two main objects: List and Item (with a list containing items as well as additional associated data).

For instance, if a user wishes to retrieve their lists, they could execute a Get request to api/Lists.

Subsequently, the user might also want to access the items within a specific list by making a Get call to api/ListItems/4, where '4' is extracted from List.listId retrieved in the previous request.

All seems to be functioning smoothly so far: utilizing the options.complete attribute of $.ajax enables me to reference a callback method, thereby streamlining these processes.

However, matters become considerably more convoluted when aiming to extract elements for all lists at once. For example, implementing a hypothetical library function known as makeGetRequest which accepts the endpoint and callback function would lead to clearer code. Yet, attempting to fetch 3 elements in a simplistic manner results in:

var success1 = function(elements){
    var success2 = function(elements){
       makeGetRequest("api/ListItems/3", finalSuccess);
    }
    makeGetRequest("api/ListItems/2", success2);
}
makeGetRequest("api/ListItems/1", success1);

Unsightly! This would typically warrant reprimand in an introductory programming course followed by guidance towards loops. But how can one employ a loop in this scenario without relying on external storage?

for(var i : values){
    makeGetRequest("api/ListItems/" + i, successFunction);
}

function successFunction(items){
    //I am invoked multiple times, each time handling only one list's set of items!
}

Even with storage mechanisms in place, it becomes necessary to ascertain when all requests have concluded and acquired their respective data before triggering a master function to compile and process the aggregate information.

Is there a tried and true approach for tackling such situations? Surely, this must have been resolved countless times prior...

Answer №1

One way to handle multiple endpoint parameters is by creating a stack:

var params = [];
var results [];

params.push({endpoint: "api/ListItems/1"});
params.push({endpoint: "api/ListItems/2"});
params.push({endpoint: "api/ListItems/3"});
params.push({endpoint: "api/ListItems/4"});

You can then implement recursion in your success handler like this:

function fetchData(endPoint) {

   var options = {} // Ajax Options
   options.success = function (data) {
       if (params.length > 0) {
           results.push({endpoint: endpoint, data: data});
           fetchData(params.shift().endpoint);
       }
       else {
          processResults(results)
       }
   }

   $.get(endPoint, options)
}

To start the process, you just need to make a single call:

fetchData(params.shift().endpoint);

Update:

If you prefer to keep everything contained within a function and avoid global scope, you can use the following approach with a callback:

function fetchAllResources(callback) {

    var endpoints = [];
    var results [];

    endpoints.push({endpoint: "api/ListItems/1"});
    endpoints.push({endpoint: "api/ListItems/2"});
    endpoints.push({endpoint: "api/ListItems/3"});
    endpoints.push({endpoint: "api/ListItems/4"});

    function fetchData(endPoint) {
        var options = {} // Ajax Options
        options.success = function (data) {
           if (endpoints.length > 0) {
               results.push({endpoint: endpoint, data: data});
               fetchData(endpoints.shift().endpoint);
           }
           else {
              callback(results)
           }
        }
       $.get(endPoint, options)
    }

    fetchData(endpoints.shift().endpoint);

}

Example of how to use it:

fetchAllResources(function(data) {
   // Process the retrieved data here
});

Answer №2

dmck's suggestion is likely the top choice. Alternatively, you could consider implementing a bulk list feature for your API to handle requests such as api/ListItems/?id=1&id=2&id=3.

Another possibility is creating an API search endpoint, if that aligns better with your preferred design aesthetic.

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

Interactive calendar control for selecting dates in JavaScript

I have implemented two date inputs in my PHP form: Arrival Date Departure Date Currently, when the Date Icon is selected, it displays the CURRENT DATE AND MONTH. What I am looking for is that when the user selects the Arrival Date first and then the De ...

Experiencing problems with the Locale setting when utilizing the formatNumber function in Angular's core functionalities

I am having trouble formatting a number in Angular using the formatNumber function from the Angular documentation. Here is my code snippet: import {formatNumber} from '@angular/common'; var testNumber = 123456.23; var x = formatNumber(Numb ...

I have been working on creating a hangman game, and although I have figured out the logic behind it, I am experiencing an issue where it is not functioning properly. After inspect

I am currently working on a basic hangman game using only HTML and JavaScript. I have the logic in place, but it doesn't seem to be functioning correctly. When I inspected the element, it showed an error saying 'undefined toUppercase.' As a ...

Unable to properly execute Fetch Delete Request

When using the Fetch API, I am sending this request: const target = e.currentTarget; fetch(target.href, { method: 'delete', }) .then(res => console.log(22)) .catch(err => console.log(err)); In addition, here is the middleware that manag ...

Implementing Ajax Requests in PHPUnit tests for Laravel applications

Working on Laravel tests using phpunit, I ran a test that involves inputting data into a textbox and clicking a button. This triggers an Ajax post request to the server, which then returns a response. If the response is a string like the one in the code sn ...

Having trouble retrieving data from the PokeAPI

Currently, I am experimenting with PokeAPI for educational purposes and attempting to run the following code: const express = require('express') const https = require('https') const app = express() const port = 3000 app.get('/&apo ...

The Firebase 'not-in' operator is malfunctioning

Within my database, there is a document located at: https://i.stack.imgur.com/OTZpd.png I am attempting to query the number of messages documents where the user's ID does not appear in the "read_by" array. This is the code I am currently using: const ...

Displaying nested object properties in HTML through iteration

What is the correct way to access them if item.NestObj.textpropertyVal is showing incorrect? success: function(data){ var html = ""; $.each(data.mainOutterObj, function (index, item) { html += "<ul&g ...

The escape character appears to be misunderstood, causing an error due to an invalid escape sequence

When using the following syntax: executeJSCommand("location.href='StatusDetails.php?CHLD=1\&JNum=1024&JTitle=';"); An error occurs displaying: Invalid Escape Sequence ...

Show notifications after being redirected to a new page

My goal is to submit a form and have the page redirected to a different URL upon submission. Currently, everything works as expected, but there is an issue with the timing of the toast message. The toast message appears immediately after the user clicks th ...

The 'SVGResize' or 'onresize' property is not available on the 'SVGProps<SVGSVGElement>' type

Using React with SVG I'm facing an issue with handling the resizing event of an svg element. I have looked into using the SVGResize and onresize events, but encountered compilation errors when trying to implement them: const msg1 = (e: any) => co ...

Issue with Z-index and wmode when using YouTube embed code on IE10

I am currently working on developing a div element that will prevent a YouTube video embedded in an iframe from playing when clicked. Instead, I want to trigger a JavaScript function upon user interaction. I have added the wmode=opaque parameter to the src ...

Obtain image URL from object properties using AngularJS

Just starting out with Angular JS and I have a question. I'm currently working on a project and I have a solution in mind, but I was wondering if there's a more "angular-esque" approach that I could take. The idea is for each videoid, there wou ...

attempting to retrieve a specific nested value using square brackets

I am attempting to track the position of an object associated with a particular row. Ultimately, I require a comprehensive object that includes both the row and the position of a "com" within that row. Below is my code snippet: (g represents a global objec ...

Parent-to-child function passed via React Hooks triggering missing dependency issue

In my current React project (v17.0.2), I am encountering a warning about the 'React Hook useEffect has a missing dependency onTogglePopup' situation. The issue is that I need to pass a shared function from a parent component to a child component ...

Is it possible to activate events on select tags even when they have the disabled attribute?

All the select options on this page have been disabled with an ID that ends in _test, and everything seems to be functioning properly. However, I would like to display a title when the selects are disabled and the mouse hovers over them. The issue arises ...

Include a sharing option within the magiczoomplus feature

My current project involves creating a WordPress site using Artisteer along with several plugins to showcase photo galleries. To enhance the user experience, I purchased an e-commerce WordPress theme which features a share button that I really like. Now, I ...

Show the result of (Firstname) on the thank you page after the form has been submitted

Need help with a PHP issue; it seems simple but I'm uncertain of the correct method, whether through jQuery or PHP. I have a contact form where I want certain field results to display on the thank you page after submitting the form: Thank you for en ...

Encountering a 404 Error When Accessing an Express.js Route with Parameters from the Client

I've set up a server route like this: (https://github.com/leptone/lang-exchange-react/blob/master/server.js) app.route('user/:username') .get((req, res) => { console.log(req.params.username) db.findOne({ username: req.pa ...

Using the && operator in an if statement along with checking the length property

Why does the console show 'Cannot read property 'length' of undefined' error message when I merge two if conditions together? //When combining two if statements using &&: for(n= 0, len=i.length; n<len; n++) { if(typeof ...