Trigger JavaScript function once all Ajax requests have completed

Seeking assistance with troubleshooting JavaScript code that is not functioning as expected.

The Application sends file names to the server via Ajax calls for processing, but I need to update the database once all imports are complete. The problem arises when the code to update the database runs before the Ajax calls execute.

I've come across suggestions online about using a promise array to track this progress, but since JavaScript is not my strong suit, I am unsure how to implement it.

Below are snippets of my current code:

Function to loop through file names:

function importFiles() {
    serverImporterInit();
    let files = getFiles();
    if (files) {
        showImportProgressModal(files);
        let looper = $.Deferred().resolve();
        $.when.apply($, $.map(files, function (file, index) {
            let fileStatusElement = document.getElementById('file-' + index + '-status');
            let fileErrorElement = document.getElementById('file-' + index + '-error');
            looper = looper.then(function () {
                setTimeout(function () {
                    return import_file_request(file, fileStatusElement, fileErrorElement);
                }, 2000);
            });
            return looper;
        })).then(function () { 
        });
    }
}

Ajax call to the server:

function import_file_request(file, element, errorElement) {
    let deferred = $.Deferred();
    fileImportStatusInProgress(element);
    $.ajax({
        type: 'POST',
        url: '/importer/manual_import',
        data: {'file': file.toString()},
        success: function(data) {
            fileImportStatusSuccess(element);
            deferred.resolve(data);
        },
        error: function (error) {
            fileImportStatusFailed(error, element, errorElement);
            deferred.reject(error);
        }
    });

    return deferred.promise();
}

While these functions are based on tutorials found online, I'm uncertain if they achieve what I originally intended, as I recently realized the need to track completion status due to another requirement.

Any guidance would be appreciated. If there are additional details I should include to improve the question, please let me know so I can update accordingly.

Update I attempted to modify the code to utilize a promise array without success.

File loop:

const importFiles = async (files) => {
    serverImporterInit()
    const filesLength = files.length
    showImportProgressModal(files);
    for (let i = 0; i < filesLength; i++) {
        const requests = files.map((file) => {
            let fileStatusElement = document.getElementById('file-' + i + '-status');
            let fileErrorElement = document.getElementById('file-' + i + '-error');
            return import_file_request(file, fileStatusElement, fileErrorElement) // Async function to import file
            .then(console.log(file + " successfully imported"))
            .catch(e => console.log('Error'))
    })
        await Promise.all(requests)
        .then(serverImporterClose())
        .catch(e => console.log(''))
    }
}

File import request to server:

function import_file_request(file, element, errorElement) {
    fileImportStatusInProgress(element);
    return new Promise((resolve, reject) => {
        $.ajax({
            type: 'POST',
            url: '/importer/manual_import',
            data: {'file': file.toString()},
            success: function(data) {
                fileImportStatusSuccess(element);
                resolve();
            },
            error: function (error) {
                fileImportStatusFailed(error, element, errorElement);
                reject();
            }
        });
    })
}

Answer №1

If you are utilizing jQuery, I have crafted a jQuery-centric solution for you without resorting to the native promise. My suggestion is to either utilize the native promise alongside the built-in fetch() function sans jQuery, or simply stick with jQuery alone.

The main approach involves employing $.map() to generate an array of promises and then waiting for their resolution using $.when(). It is crucial to remember to always return the jQuery promise.

function importFiles() {
  var files = getFiles();
  if (files) {
    showImportProgressModal(files);
    serverImporterInit();
    var promises = $.map(files, function(file, index) {
      let fileStatusElement = document.getElementById('file-' + index + '-status');
      let fileErrorElement = document.getElementById('file-' + index + '-error');

      return import_file_request(file, fileStatusElement, fileErrorElement)
    })
    $.when.apply($, promises).then(function(results) {
      serverImporterClose();
      results.forEach(function(result) {
        if (result) {
          console.log("yay, success");
        }
        else {
          console.log("failed");
        }
      })
      hideImportProgressModal(files);
    });
  }
}

function import_file_request(file, element, errorElement) {
    fileImportStatusInProgress(element);
    // Ensure to return the promise at this point
    return $.ajax({
        type: 'POST',
        url: '/importer/manual_import',
        data: {'file': file.toString()},
        success: function(data) {
            fileImportStatusSuccess(element);
            return true;
        },
        error: function (error) {
            fileImportStatusFailed(error, element, errorElement);
            return false;
        }
    });
}

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

What is the best way to automatically set today's date as the default in a datepicker using jQuery

Currently utilizing the jQuery datepicker from (http://keith-wood.name/datepick.html), I am seeking to customize the calendar to display a specific date that I select as today's date, rather than automatically defaulting to the system date. Is there a ...

Where should the webapp files for a Node.js application be located within the server directory?

Can someone help clarify a question I have been struggling with? I have created a nodejs webapp with a specific directory structure, as shown in the screenshot. This app will eventually incorporate MongoDB and store a large number of audio files. I am usi ...

Proceed with the next AJAX request only when the previous one has successfully completed

Currently, I am working on a process where PDFs are generated in the background using AJAX calls. The generation of these PDF files usually takes around one second each. Although the process is functional, I have encountered an issue with memory depletion ...

Alternative method to jQuery's "find" selector

$('.wrapper a').filter('a'); //returns all anchors I am trying to find a way to select all anchor elements using a specific selector. The issue is that the find method only looks at descendants, so I need an alternative solution. Any s ...

When a child component is updated, React does not automatically re-render

My goal is to pass the email from the SigninForm back to the App component and trigger a re-render when the email is updated. I attempted to follow the structure outlined in a previous question on Stack Overflow, but unfortunately, I couldn't get the ...

What could be causing input to be blocked in certain situations while using my Angular directive with compile function?

Recently, I created a directive that adds a class based on a certain condition. You can find the code snippet at the end of this question. The directive functions as expected in a simple use case where it's applied to a required field: <input typ ...

developing a shader that transitions between day and night based on the movement of a light source

I've set up a scene with a sphere illuminated by a DirectionalLight to simulate the sun shining on Earth. My goal is to incorporate a shader that displays the earth at night on the unlit portions of the globe and during the day on the lit areas. Event ...

The proper method for retrieving FormData using SyntheticEvent

I recently implemented a solution to submit form data using React forms with the onSubmit event handler. I passed the SyntheticBaseEvent object to a function called handleSubmit where I manually extracted its values. I have identified the specific data I n ...

Using nodeJS's util module to format and pass an array

I've been using util.format to format strings like this: util.format('My name is %s %s', ['John', 'Smith']); However, the second parameter being an array ['John', 'Smith'] is causing issues because m ...

AngularJS: The dynamic setting for the stylesheet link tag initiates the request prematurely

I'm encountering a problem that is somewhat similar (although not exactly the same, so please be patient) to the one discussed in Conditionally-rendering css in html head I am dynamically loading a stylesheet using a scope variable defined at the sta ...

Exploring the Crossroads of JSP and External Javascript Documents

I am new to using external JavaScript files (*.js). I have my JSP file ready, but my manager wants me to incorporate graphics into it. After searching, I found some *.js files. However, I am unsure of how to connect them with my JSP page. I need a way to ...

Establish a connection to an SSH server using Node.js code, specifying the SSH key and server hostname for

Having VPN access allows me to SSH into the server using the following command in the terminal: ssh qa-trinath01.my-qa This command works perfectly fine when executed from the terminal. However, when attempting to connect via Node.js, I encounter issues ...

Implement image uploading feature with Ant Design library in a React JS application

I need assistance with a basic application that allows users to upload images. Once the image is uploaded and the user clicks on the get data from upload button, the result should be displayed in the console as console.log("Received values of form: ", valu ...

Encountering an async issue with npm exiftool in JavaScript

I'm facing issues with npm exiftool usage. (https://www.npmjs.com/package/exiftool) I'm attempting to perform some tasks using it. Iterate through image files in a specific folder Retrieve 'xpKeywords' data of each image file Write th ...

Get rid of the spaces in web scraping <tr> tags using Node.js

I've encountered a problem that goes beyond my current knowledge. I'm attempting to web-scrape a specific webpage, targeting the <tr> element in nodejs. Although I can successfully retrieve the content, it seems that the format is not as cl ...

What are the best practices for managing data input effectively?

I am facing a challenge with input validation. I need to restrict the input to only accept strings of numbers ([0-9]) for the entity input field. If anything else is entered, I want to prevent it from overwriting the value and displaying incorrect input. I ...

Implementing dynamic title rendering based on image in vue.js

This is the code I'm working with, aiming to display slider data. My goal is that if image[0] appears on the slider, it should return title [0]. I'm quite curious about what could be missing in my setup.code-image ...

Implementing a persistent header on a WordPress site with Beaver Builder

My website URL is: . I have chosen to use beaver builder for building and designing my website. I am in need of a fixed header that can display over the top of the header image. Here is the code snippet that I currently have: <div id="header">html ...

Generating a JSON outcome from a SQL server database

My SQL server has the following table layout: Table ( id int, title varchar(40), start Date(), end Date(), allDay bool, username varchar(40) ); I found some code on this blog to create a JSO ...

Automatic Addition of Row Numbers Enabled

I'm currently exploring coding and experimenting with creating a scorekeeper for family games. I've managed to add rows dynamically and automatically sum up the entered information in the "total" row at the bottom. However, I'm facing an iss ...