Search code examples
javascriptnode.jstypescriptdomweb-analytics

Execute A Function When All xmlHttpRequests Are Complete


BRIEF

I have a website which gets data from an API. So it makes some post and get requests to a server once the website is opened. Let us assume it makes 5 different xmlHttpRequests as soon as the page loads but we cannot exactly know the time each call takes from start to finish.

FOR EXAMPLE

Call to one endpoint takes 2 seconds to complete and the other one takes 1 second to complete. So that means after 2 seconds both the calls are said to be finished.

TO-DO

I want to execute a function after all the xmlHttpRequests are complete because I am using window.performance.getEntries() to fetch all the requests initiated by the webpage and send it to my server as I am doing a web analytics project in which I need to access the times taken by each network request and convert the data into a chart.

EXTRA-QUESTION OR HINT

Is there any event that can be attached to the window as shown below to listen for all the network calls and execute my piece of code when all are finished.

      window.addEventListener("load", function (event) {
       //execute some code here
      }

In the load event I am not able to capture all the requests by using performance.getEntries() because load fires before the ajax calls are finished.

As shown above I ask. Is there any trick or any event or anything in JavaScript by which we can wait untill all the XMLHTTPREQUESTS are finished and then execute some code.


Solution

  • WORKING SOLUTION

    We can track browser AJAX calls using the code below :

      const ajaxCallStatus = () => {
       window.ajaxCalls = 0; // initial ajax calls
       window.ajaxEndpoints = []; // keeping track of all ajax call urls (endpoints) 
       const origOpen = XMLHttpRequest.prototype.open;
       XMLHttpRequest.prototype.open = function() {
       window.ajaxCalls++;
       this.addEventListener('load', (event) => {
        if (!window.ajaxEndpoints.includes(event['currentTarget'].responseURL)) {
          window.ajaxEndpoints.push(event['currentTarget'].responseURL);
        }
        window.ajaxCalls--;
        switch (window.ajaxCalls) {
        case 0: // when ajax calls finish this runs
          addData(window.ajaxEndpoints);
        break;
        }
         });
        origOpen.apply(this, arguments);
        }
       }
    

    ADD DATA FUNCTION - Used for sending data to some backend.

    function addData(arr, origOpen) { 
       XMLHttpRequest.prototype.open = origOpen;
       axios.post('url', data)
      .then((res) => console.log(res))
      .catch((err) => console.log(err));
    }