Another option instead of using async:false

For my for loop, I am trying to make AJAX calls in a specific sequence. The responses need to be stored in an array with elements in the correct order. Despite attempting various solutions from similar questions, none have been successful except setting async: false. Although I understand that using async: false is not recommended, I am unsure about alternative methods to achieve sequential responses.

Furthermore, when mapping the array to render elements, some methods resulted in errors stating "cannot read map of undefined."

This is my current approach:

auto_video_jobs_array = [];
        for (var i = 0; i < this.state.current_auto_video_jobs_urls.length; i++) {
            this.get_auto_video_jobs_array(i)
        }

get_auto_video_jobs_array(i) {
        var that = this;
        var settings_3 = {
            "async": false,   //this is made false to get array element in right sequence
            "crossDomain": true,
            "url": that.state.current_auto_video_jobs_urls[i],
            "method": "GET",
            "headers": {
                Authorization: "Token " + that.props.token_Reducer.token
            },
            success: function (response, textStatus, jQxhr) {
                console.log("success")
                console.log("value of i is " + i)
            },
        }

        $.ajax(settings_3).done((response) => {
            auto_video_jobs_array.push(response)
            if (i == that.state.current_auto_video_jobs_urls.length - 1) {
                console.log("i reached last value")
                that.setState({current_auto_video_jobs: auto_video_jobs_array})
                console.log("current jobs are" + that.state.current_auto_video_jobs)
            }
        });
    }

I also attempted an alternative implementation which failed and threw an error about being unable to read map of undefined:

//initialize index counter
            var i = 0;
            var that = this;
            function next() {
                $.ajax({
                    async: true,
                    "crossDomain": true,
                    "url": that.state.current_auto_video_jobs_urls[i],
                    "method": "GET",
                    "headers": {
                        Authorization: "Token " + that.props.token_Reducer.token
                    },
                    success: function(response, textStatus, jQxhr){
                        ++i;
                        if(i >= that.state.current_auto_video_jobs_urls.length) {
                            // run function here as its the last item in array
                            console.log("i reached last value")
                            that.setState({current_auto_video_jobs: auto_video_jobs_array})
                            console.log("current jobs are" + that.state.current_auto_video_jobs)
                        } else {
                            // do the next ajax call
                            auto_video_jobs_array.push(response)
                            next();
                        }
                    }
                });
            }

            // start the first one
           next();

I am seeking a method to perform async calls while ensuring responses come back incrementally. Using promises has been suggested, although it's unfamiliar territory for me. If promises are the solution, how should I implement them?

Answer №1

Essentially, the task at hand involves executing numerous asynchronous tasks in a sequential manner. This necessitates utilizing a method like async.series from a library that offers such functionality. Fortunately, there exists a standalone package that delivers similar capabilities; you may use its (fairly concise) source code as a foundation for crafting your own solution.

The snippet below presents a slightly tweaked version of the source code from 'async-series', which has been refined to focus on node.js environment specifics:

/**
 * @author Hugh Kennedy
 * @url https://github.com/hughsk/async-series
 * @license MIT
 */
function series(arr, ready, safe) {
    var length = arr.length, orig;
    var nextTick = 'undefined' !== typeof setImmediate ? setImmediate : setTimeout;

    if (!length) {
        return nextTick(ready, 1)
    }

    function handleItem(idx) {
        arr[idx](function (err) {
            if (err) return ready(err)
            if (idx < length - 1) return handleItem(idx + 1)
            return ready()
        })
    }

    if (safe) {
        orig = handleItem
        handleItem = function (idx) {
            nextTick(function () {
                orig(idx)
            }, 1)
        }
    }

    handleItem(0)
}

With this function in your toolkit, seamlessly passing a list of tasks to execute and populating your array becomes a simple process, ensuring their sequential execution.

Answer №2

Using promises can simplify this task greatly. Keep in mind that Internet Explorer lacks built-in promise support, but you can enable it by utilizing a library such as Bluebird:

const self = this;
let autoVideoJobsArray;

// Waiting for all promises to resolve
Promise.all(this.state.currentAutoVideoJobsUrls.map(function (url) {
    // Mapping each URL to a promise for querying the endpoint
    const settings = {
      "crossDomain": true,
      "url": url,
      "method": "GET",
      "headers": {
        Authorization: "Token " + self.props.tokenReducer.token
      }
    };

    return $.ajax(settings);
  }))
  .then(function(results) {
    // Results represent an array of query results, in the same order as the original URLs
    autoVideoJobsArray = results;  
    self.setState({
      currentAutoVideoJobs: results
    });
  });

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

Are there any unique purposes for _id in MongoDB?

I have a nodejs application that defines answers like this: var answerSchema = mongoose.Schema({ session : String, // the ID of the session question : String, // the ID of the question answer : Number // the selected answer (1-5) }); whic ...

Is there a way to display the data retrieved from an ajax request within a div element?

I'm having trouble displaying the data from my ajax request inside <div class="l_p_i_c_w"></div>. What could be causing this issue? I know that the function in my_file.php is functioning properly because when I refresh the page, the data a ...

Automatic page switch upon dropdown selection

I'm not very proficient in JavaScript and I want to modify a form so that it automatically updates when a dropdown option is selected, without needing to click a separate "Go" button. How can I adjust the code below? It contains three different dropd ...

What should we name this particular style of navigation tab menu?

What is the name of this tab menu that includes options for next and previous buttons? Additionally, is there a material-ui component available for it? https://i.sstatic.net/0m9rH.png ...

The assets path is the directory within the installed package that houses the main application files following the completion of a

I have a Vue.js UI component that is internally built using webpack. This reusable UI component library references its images as shown below: <img src="./assets/logo.png"/> <img src="./assets/edit-icon.svg"/>   <i ...

Invoking an ASP.NET page with JavaScript and transmitting a response

I'm struggling with a JavaScript script that makes an AJAX call to a service: $.ajax({ type: "GET", url: ServiceAddress + "/Service.aspx?action=LoadRandomImagePath&userID=" + USER_ID, success: function (result) { ...

Integration of Foundation-Apps Angular website with unit testing using Karma-Jasmine

While attempting to run a karma jasmine unit test, I encountered an issue with using angular-mocks and foundation-apps. It's possible that I overlooked something in my setup. I've provided an example project on github for further evaluation due t ...

Implementing server-side validation measures to block unauthorized POST requests

In my web application using angular and node.js, I am in the process of incorporating a gamification feature where users earn points for various actions such as answering questions or watching videos. Currently, the method involves sending a post request t ...

Pass PHP date to JavaScript and increase its value

I'm looking to retrieve the server time with PHP and store it in a JavaScript variable. Once stored, I'd like it to continuously increment. Below is the code snippet: function initTime(date){ var today=new Date(date); var h=today.getHours(); v ...

What is the best way to access and retrieve object properties in JavaScript?

Hey there! I'm working on a project using React with the React Context API. My main component is App.js, which is a functional component containing the app's logic. Within this component, I've set up state using useState for context: const ...

Stop the Nav bar item from collapsing

Alright, let's talk about the scenario: The situation is that I have a basic, plain, nav nav-tabs navigation bar with a few elements and a rightmost item (with pull-right) positioned as an <li> element which includes a dropdown. As the window ...

Amazon Lex: Transforming Speech to Text with Audio Technology

Is there a JavaScript SDK provided by Amazon for converting audio files to text using Amazon Lex? I am currently working on a Node.js application and would like to achieve this functionality. ...

Should I be concerned? - "Revealing chrome JavaScript objects..."

Recently, I've been noticing an error in Firebug that mentions something about exposing chrome JS objects to content without "__exposedProps__," but I'm not sure what it really means or if it's something I should worry about: The error me ...

Guide to obtaining every conceivable index combination in a sequential manner for the same attribute within an object array

I have an array of objects structured like this: [{ property1: 10 }, { property1: 13 }, { property1: 15 }, { property2: 2 }] I am looking to create a function that will generate an object containing all possible index combinations (from left to right) of ...

The registration for the api did not occur following the initialization of dataTables

Desiring to incorporate APIs in dataTables, such as employing table.ajax.url().load() and table.data(), following its initialization through the code below: table = $elem.dataTable(options); Unfortunately, none of the methods like ajax or data were assoc ...

Manipulate a property within an array using JavaScript and AngularJS

I am working with an AngularJS model that looks like this: $scope.Model = { Users : [{ UserId: '', FirstName: '', LastName: '' }], Products :[{ ProductId: '', ...

What is the appropriate way to assign a scope property in an angular controller when it becomes accessible?

In my code, there exists a global JavaScript object known as instance_ This object includes a property named current_ Later on, another property called dataset_ is assigned to current_ Therefore, we can access this dataset_ property by using instance_.c ...

Looking to arrange an object by the value of a nested object in Typescript/Angular?

I'm currently developing an Angular 9 application focused on covid-19 cases, and I need to arrange my objects by the value of nested objects. Here is the dataset that I want to organize alphabetically based on the 'state' field values: stat ...

Mastering the Proper Application of Task.WhenAll()

I have encountered an issue while trying to utilize Task.WhenAll for awaiting the completion of multiple tasks. Here is my code - it's intended to initiate several asynchronous tasks, each responsible for fetching a bus route and adding it to a local ...

How does assigning a checkbox's value as 'undefined' result in the addition of ng-invalid?

I'm facing an issue with a checkbox in my Angular project. The checkbox has a false value of undefined, and even though it's not marked as required, the form doesn't validate when I check and uncheck it. This is because the class ng-invalid ...