March 30, 2015

JavaScript OData Pagination with synchronous calls

One limit of the OData endpoint is that the response can only include up to 50 records, so if your result set has more records it's necessary to reiterate the request using the url inside the __next property contained inside the returned object.

The following code shows how to fetch the request using synchronous calls, because sometimes you need (or want) to block the user :)
function getODataRecords(ODataUrl) {

    // we return an object with a similar structure as the OData endpoint
    var allRecords = new Object();
    allRecords.results = new Array();
    
    // we loop until we have an url to query
    var queryUrl = ODataUrl;
    while(queryUrl != null) {

        // we build the request
        var ODataRequest = new XMLHttpRequest(); 
        ODataRequest.open("GET", queryUrl, false); // false = synchronous request
        ODataRequest.setRequestHeader("Accept", "application/json"); 
        ODataRequest.setRequestHeader("Content-Type", "application/json; charset=utf-8"); 
        ODataRequest.send();

        if (ODataRequest.status === 200) {
            var parsedResults = JSON.parse(ODataRequest.responseText).d;
            if (parsedResults != null && parsedResults.results != null) {

                // we add the results to our object
                for (var i = 0; i < parsedResults.results.length; i++) {
                    allRecords.results.push(parsedResults.results[i]);
                }

                // check if there are more records and set the new url, otherwise we set to null the url
                if (parsedResults.__next != null) {
                    queryUrl = parsedResults.__next;
                } else {
                    queryUrl = null;
                }
            }
        } else {
            // if the request has errors we stop and return a null result
            queryUrl = null;
            allRecords = null;
        }
    }

    return allRecords;
}

// sample function to return all the accounts
function GetAllAccounts() {
    var serverUrl;
    if (Xrm.Page.context.getClientUrl !== undefined) {
        serverUrl = Xrm.Page.context.getClientUrl();
    } else {
        serverUrl = Xrm.Page.context.getServerUrl();
    }
    var ODataPath = serverUrl + "/XRMServices/2011/OrganizationData.svc";
    var accountQueryUrl = ODataPath + "/AcccountSet?$select=AccountNumber,Name";

    // call our new method
    var retrievedAccounts = getODataRecords(accountQueryUrl);

    // alert each result
    if (retrievedAccounts != null) {
        for (var i = 0; i < retrievedAccounts.results.length; i++) {
            alert(retrievedAccounts.results[i].Name + " - " + retrievedAccounts.results[i].AccountNumber);
        }
    }
}

0 comments:

Post a Comment