Search code examples
javascriptajaxwaitsynchronouspageload

Using one function to handle multiple Ajax requests - returning same results on page load


I'm writing some code where there will be one function (doAjax) to handle all the requests for different functionalities. This is working fine when used in the normal sense (clicking buttons, etc), but I'm trying to call a few things when the page is loaded to initialise the state of the application.

Here's the Ajax function:

function doAjax(type, action, data = null){
    return new Promise(function(res,rej){
        xhr = new XMLHttpRequest();
        xhr.open(type, '/inc/functions.php?action='+action, true);
        xhr.timeout = 20000;
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onload = function() {
            if (this.status === 200) {
                res(xhr);
            } else {
                console.log("some xhr error occured");
                rej("some xhr error happened");
            }
        };
        xhr.send(data); 
    });
}

And here are a couple of examples of functions that send requests to this:

/* get file structure of files */
function buildTree(){
     doAjax('GET', 'get_files').then(r => {
         var res = JSON.parse(r.response);
         console.log(res);
         /*
              the json is processed here and stuff 
              is displayed on the front end
         */

     }
}

/* get user data from database */
function populateShare(){
    doAjax('GET', 'social_populate').then(r => {
        var res = JSON.parse(r.response);
        console.log(res);
        /*
            again, the json received from the database is 
            processed and output to the front end
        */
    }
}

I should also mention these functions are also bound to click listeners, so are used in the application later as well as onload!

Now, the problem is when I try and execute both of these on page load as a kind of initialise function (to set up the application ready for use). If I run the below:

 function init(){
     buildTree();
     populateShare();
 }
 init(); //called later

Both console.logs output the same result - the return from social_populate (called from populateShare()).

So my question ultimately is whether there are any ways to queue function calls in the init() function, waiting for each to finish before moving onto the next? There may be more functions that need to be called on init(), some also involving Ajax requests.

I have tried the following, found in another thread - but unfortunately returns the same result:

async function initialise(){
     try {
         const p1 = buildTree();
         const p2 = populateShare();
         await Promise.all([p1, p2]);
     } catch (e) {
         console.log(e);
     }
}

I know I could load the entire lot from the back end and return in one huge JSON, but I'm more curious to whether the above can be achieved! I feel like I've entered some kind of synchronous request death loop, or I'm missing something blatantly obvious here!

Also, no jQuery please!

Thanks!


Solution

  • You appeared to have accidentally used global variable when you declare xhr which was overwritten at each call.

    Try let xhr = new XMLHttpRequest();