Jackson Christopher
Jackson Christopher

Reputation: 101

Concat results of multiple AJAX calls into single variable

I would like to call 2 recursive API calls to generate a JQuery datatables page date range 2016-2021. The year filter on these API calls below split the API response to overcome the 5000 item list limit threshold established by Sharepoint Online.

I am unable to concat all results into my var allResults. With the code below, i only get the results generated for 2021. However, I can see that 12 successful API calls are made via Chrome XHR for years 2016-2021 but the results are not being concat into the var. Kindly advise.

var results;
var allResults = [];

$(document).ready(function () {
    load();
});

function load() {
    for (let year = 2016; year < 2022; year++) {
        var yearh1 = $.ajax({    
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+(year-1)+"-12-31T20:00:00.000Z')%20and%20(Col_Date%20lt%20datetime'"+year+"-06-01T00:00:00.000Z')",    
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
            success: mySuccHandler, error: myErrHandler}); 

        var yearh2 = $.ajax({    
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+year+"-06-01T00:00:00.000Z')%20and%20(Col_Date%20le%20datetime'"+year+"-12-31T00:00:00.000Z')",    
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
            success: mySuccHandler, error: myErrHandler}); 
    }

    function mySuccHandler(a) {
        results = a.d.results;
        if (allResults.length > 0)
            allResults = allResults.concat(results);
        else
            allResults = results;        
    }
    function myErrHandler(data, errorCode, errorMessage) {
        console.log("Could not complete call: " + errorMessage);        
    };

   $.when(yearh1, yearh2).done(function(a1, a2){
      // console.log(allResults);
    $('#table_id').DataTable({
        data:allResults,
        dom: 'Bfrtip',
        columns: [
                    { data: "Title" },
                    { data: "Reg_x0020_No" },
        ]
    });
   });  
};

Addendum

After reading some answers I added a var allRequests. This now allows me to store results from all API calls, but does not concat results and pass it to datatables for table rendering.

var results;
var allResults = [];
var allRequests = [];
$(document).ready(function () {
    load();
});

function load() {
for (let year = 2016; year < 2022; year++) {
    var yearh1 = $.ajax({    
        url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Incident_x0020_Date%20ge%20datetime%27"+(year-1)+"-12-31T20:00:00.000Z%27)%20and%20(Incident_x0020_Date%20lt%20datetime%27"+year+"-06-01T00:00:00.000Z%27)",    
        type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
        success: mySuccHandler, error: myErrHandler}); 
    var yearh2 = $.ajax({    
        url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Incident_x0020_Date%20ge%20datetime%27"+year+"-06-01T00:00:00.000Z%27)%20and%20(Incident_x0020_Date%20le%20datetime%27"+year+"-12-31T00:00:00.000Z%27)",    
        type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"},    
        success: mySuccHandler, error: myErrHandler}); 

       allRequests.push(yearh1);
       allRequests.push(yearh2); 
}       
    function mySuccHandler(a) {
        results = a.d.results;
        if (allResults.length > 0)
            allResults = allResults.concat(results);
        else
            allResults = results;
    }

    function myErrHandler(data, errorCode, errorMessage) {
        console.log("Could not complete call: " + errorMessage);        
    };

   $.when($, allRequests).done(function(a1, a2){
    $('#table_id').DataTable({
        data:allResults,
        dom: 'Bfrtip',
        columns:[
                    { data: "Title" },
                    { data: "Reg_x0020_No" }
                ]
    });
   });  
};

Upvotes: 0

Views: 209

Answers (1)

trincot
trincot

Reputation: 350300

The loop overwrites the values of yearh1 and yearh2 in each iteration, so that is why the $.when() call will only deal with the results from the last two requests.

You could collect the responses into an array instead of assignment to yearh1 and yearh2, and then spread that array to $.when().

Also, I would suggest not using the success handler, but deal with the data only when you perform the $.when() call.

Here is how that could look:

function load() {
    const promises = [];
    for (let year = 2016; year < 2022; year++) {
        promises.push($.ajax({
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+(year-1)+"-12-31T20:00:00.000Z')%20and%20(Col_Date%20lt%20datetime'"+year+"-06-01T00:00:00.000Z')",
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"}
        }), $.ajax({    
            url: "SPO_Site/_api/web/lists/getbytitle('List_Name')/items?$top=5000&$select=*&$filter=(Col_Date%20ge%20datetime'"+year+"-06-01T00:00:00.000Z')%20and%20(Col_Date%20le%20datetime'"+year+"-12-31T00:00:00.000Z')",   
            type: "GET", dataType: "json", headers: {"accept": "application/json;odata=verbose"}
        })); 
    }

    function myErrHandler(data, errorCode, errorMessage) {
        console.log("Could not complete call: " + errorMessage);        
    }

    $.when(...promises).then(function(...responses){
        const allResults = responses.map(x => x[0].d.results);
        console.log(allResults);
        $('#table_id').DataTable({
            data:allResults,
            dom: 'Bfrtip',
            columns: [
                { data: "Title" },
                { data: "Reg_x0020_No" },
            ]
        });
    }).catch(myErrHandler);  
}

Finally, consider using the native Web API for dealing with HTTP requests and Promises: fetch instead of $.ajax, Promise.all instead of $.when. The interface is slightly different, but it is worth to make the transition to these standards.

Upvotes: 1

Related Questions