2
votes

I have an API that handles server-side paging, filtering, and sorting. In order to build the dataSource url, I set up transport.read as a function (as described in the documentation). This works fine, except that my API is called twice: once during the initial ajax request, and then again after options.success(result) is called. Anyone else run into this? What exactly does options.success() do that causes another XHR GET request when it already has the data it needs?


UPDATE:

Thanks to Rick's comment below, I did what I should have done this morning and start commenting other kendo grid config code out to see what would happen. Turns out the function that executes when the dataSource is changed is causing the second API call. This is needed so when the grid is sorted, the URL sent to the API contains the updated sorting request. I guess now I'm confused why the change event fires on the initial load when I'm already setting up the default sort parameters. Updated my config below.


Here's my dataSource transport config:

var initGrid = function (take, skip, currPage, field, direction, model, gridElement, cols) {
    //set up dataSource
    var dataSource = new kendo.data.DataSource({
        transport: {
            read: function (options) {
                $.ajax({
                    url: apiUrl + '?take=' + take + '&skip=' + skip + '&page=' + currPage + '&pageSize=' + take + '&sort%5B0%5D%5Bfield%5D=' + field + '&sort%5B0%5D%5Bdir%5D=' + direction,
                    dataType: 'json',
                    success: function (result) {
                        // by the time this is reached, the API has already been called once
                        // the result variable contains the necessary data
                        options.success(result); // the API is called again when this line executes
                    },
                    error: function (result) {
                        options.error(result);
                    }
                });
            }
        },
        change: function () {
            var currentSorting = JSON.stringify(this.sort());
            if (currentSorting != sorting) {
                sorting = currentSorting;
                this.sort(JSON.parse(sorting));
            }
            field = JSON.parse(sorting)[0].field;
            direction = JSON.parse(sorting)[0].dir;
        },
        sort: { field: field, dir: direction }, //default sort

        ....

    }
}
1
It's most likely some other code you have that is causing this. I can create a simple example of just a datasource exactly like you have and it only calls the URL once. - Rick S
Excellent comment. Updated my question as a result. Had tried breakpoints to see if the code was hit, but didn't comment it out before. Argh. - esvendsen

1 Answers

3
votes

Turns out the problem was using the dataSource change event to try and detect when sorting had been updated. I didn't realize that I already had access to all the updated properties within the "options" parameter for the transport.read function. So instead of listening for the change event, updating variables, and manually calling sort, I simply used the options object when I constructed my URL in the first place. Take, skip, page, pageSize, and sort are all there. This way, Kendo just handles everything on its own. New config:

var initGrid = function (model, gridElement, cols) {
    //set up dataSource
    var dataSource = new kendo.data.DataSource({
        transport: {
            read: function (options) {
                $.ajax({
                    url: apiUrl + '?take=' + options.data.take + '&skip=' + options.data.skip + '&page=' + options.data.page + '&pageSize=' + options.data.pageSize + '&sort%5B0%5D%5Bfield%5D=' + options.data.sort[0].field + '&sort%5B0%5D%5Bdir%5D=' + options.data.sort[0].dir,
                    dataType: 'json',
                    success: function (result) {
                        options.success(result);
                    },
                    error: function (result) {
                        options.error(result);
                    }
                });
            }
        },
        sort: { field: 'Id', dir: 'desc' }, //default sort

        ....