kyle
kyle

Reputation: 527

Displaying AJAX responses in the same order they were sent out without using synchronous requests

I'm sending out multiple getJSON requests, and after each request I build out a panel and initialize a 3rd party hierarchical grid with the data. The problem I'm having is that panels aren't being created in the order the requests are sent out but in the order they come back. I think I've dug myself into a whole but I really don't want to have to re-engineer this if I don't have to.

var _grids = {
        ServiceGrid: {
            id: 0,
            parentUrl: _SERVICE_CONTENT_URL,
            childUrl: _SERVICE_HISTORY_URL,
            parentElementName: "ServiceTypeName",
            childElementName: "ServiceLogEntries",
            childPrimaryKey: "LogID",
            tableName: "Service",
            data: [],
            parentColumns: [...],
            childColumns: [...]
        },
        ServiceItemGrid: {
            id: 1,
            parentUrl: _SERVICE_ITEM_CONTENT_URL,
            childUrl: _SERVICE_ITEM_HISTORY_URL,
            parentElementName: "PackageServiceItemName",
            childElementName: "ServiceItemLogEntries",
            childPrimaryKey: "LogID",
            tableName: "Service Item",
            data: [],
            parentColumns: [...],
            childColumns: [...]
        }
    };

function prepareDataForGrid(_grids, id) {
    var tableIdIncrementor = 0;
    var $panelGroup = $("<div>").addClass("panel-group");

    // Append Accordion
    $panelGroup.attr("id", "accordion");
    $panelGroup.appendTo("#placeholder");


    $.each(_grids, function(index, grid) {
        var parentUrl = grid.parentUrl,
            childUrl = grid.childUrl,
            //Request data
            parentData = getApiDataAjax(parentUrl, id),
            childData = getApiDataAjax(childUrl, id);

        $.when(parentData, childData).done(function (parentDataResult, childDataResult) {
            //Combine child to parent
            combineElements(parentDataResult[0], childDataResult[0], grid);
            // Hydrate grid.data with combined data
            grid.data = parentDataResult[0];

            //loop through grids, build panels for each parent
            $.each(grid.data.result, function(index, value) {

                appendhtml(grid, value, tableIdIncrementor);

                //Create hierarchical grid  
                $("#" + tableIdIncrementor).igHierarchicalGrid({
                    initialDataBindDepth: 1,
                    dataSource: JSON.stringify(value),
                    dataSourceType: "json",
                    responseDataKey: "result",
                    autoGenerateColumns: false,
                    primaryKey: "ID",
                    columns: grid.parentColumns,
                    autoGenerateLayouts: false,
                    defaultChildrenDataProperty: value[grid.childElementName],
                    columnLayouts: [
                        {
                            key: grid.childElementName,
                            autoGenerateColumns: false,
                            primaryKey: value.childPrimaryKey,
                            columns: grid.childColumns
                        }
                    ]
                });

                tableIdIncrementor++;
            });
        });
    });
}

I could possibly make all the panels first and attach the grids to the panels via id's but it would be so much simpler if I could append panels and grids in the order the requests where sent out.

Thanks.

Upvotes: 1

Views: 88

Answers (1)

Kevin B
Kevin B

Reputation: 95018

One simple solution would be to create and append a div to the target div while you're looping, then insert data into each div as the data arrives.

$.each(function () {
    var $thisDiv = $("<div>").appendTo("#targetDiv");
    $.when(doThis,doThat).done(function (result1, result2) {
        $thisDiv.append(result1).append(result2);
    });
});

Though, I would prefer building the html structure beforehand and inserting all at once, just because I prefer to touch the dom as little as possible.

Upvotes: 2

Related Questions