1

I'm using dataTable with server side processing. I want to send token as custom parameter to the server. Token is set by AJAX. When AJAX request on dataTable fired, token parameter that send always null. I think it is because AJAX request on dataTable fired before get token process finished. Here are ways that I already tried.

1. Using ajax.data

    function GetToken() {
        var token;
        $.get("/User/GetToken?_=" + new Date().getTime(), function (token) {
            token= token;
        });
        return token;
    }

    var dataTable = $('#dataTable').DataTable({
        serverSide: true,
        pagingType: 'full_numbers',
        scrollY: false,
        scrollX: true,
        sort: false,
        fixedColumns: true,
        autoWidth: true,
        language: {
            paginate: {
                first: "<<",
                previous: "<",
                next: ">",
                last: ">>",
            }
        },
        pageLength: 10,
        lengthMenu: [[2, 5, 10, 25, 50], [2, 5, 10, 25, 50]],
        columns: [
                { "data": "Name", "autoWidth": true },
                { "data": "Address", "autoWidth": true },
                { "data": "Gender", "autoWidth": true },
        ],
        ajax: {
            url: '@Url.Action("LoadData", "Student")',
            type: 'POST',
            data: { token: GetToken() }
            dataSrc: "Data"
        }
    });

2. Using preXhr.dt

    var dataTable = $('#dataTable')
        .on('preXhr.dt', function (e, settings, data) {
            $.get("/User/GetToken?_=" + new Date().getTime(), function (token) {
                data.token = token;
            });
        })
        .DataTable({
            serverSide: true,
            pagingType: 'full_numbers',
            scrollY: false,
            scrollX: true,
            sort: false,
            fixedColumns: true,
            autoWidth: true,
            language: {
                paginate: {
                    first: "<<",
                    previous: "<",
                    next: ">",
                    last: ">>",
                }
            },
            pageLength: 10,
            lengthMenu: [[2, 5, 10, 25, 50], [2, 5, 10, 25, 50]],
            columns: [
                    { "data": "Name", "autoWidth": true },
                    { "data": "Address", "autoWidth": true },
                    { "data": "Gender", "autoWidth": true },
            ],
            ajax: {
                url: '@Url.Action("LoadData", "Student")',
                type: 'POST',
                dataSrc: "Data"
            }
        });

3. Add looping for delay on preXhr.dt

    var isTokenChange = false;
    var dataTable = $('#dataTable')
        .on('preXhr.dt', function (e, settings, data) {
            $.get("/User/GetToken?_=" + new Date().getTime(), function (token) {
                data.token= token;
                isTokenChange = true;
            });

            while(!isTokenChange) {

            }

            isTokenChange = false;
        })
        .DataTable({
            serverSide: true,
            pagingType: 'full_numbers',
            scrollY: false,
            scrollX: true,
            sort: false,
            fixedColumns: true,
            autoWidth: true,
            language: {
                paginate: {
                    first: "<<",
                    previous: "<",
                    next: ">",
                    last: ">>",
                }
            },
            pageLength: 10,
            lengthMenu: [[2, 5, 10, 25, 50], [2, 5, 10, 25, 50]],
            columns: [
                    { "data": "Name", "autoWidth": true },
                    { "data": "Address", "autoWidth": true },
                    { "data": "Gender", "autoWidth": true },
            ],
            ajax: {
                url: '@Url.Action("LoadData", "Student")',
                type: 'POST',
                dataSrc: "Data"
            }
        });

For third way, it's works but I think it's not a good solution. My question is what is a good solution to hold or delay ajax request on datatable until token has received?

3 Answers 3

1

You can chain your calls, Only when you receive a token fire the datatable initialization.

function GetToken() {
    var token;
    $.get("/User/GetToken?_=" + new Date().getTime(), function (token) {
        initializeTable(token);
    });
}

initializeTable(token){
// Here initialize ur data table with the passed token.
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is a correct answer. More elegantly this could be done in a (function() {...}) struct i.e self exeucting function that fires the datatable initialisation as soon the server responds back.
@SubirKumarSao thanks for your answer. But I think your implementation only get token once and will use same token for all events in datatable (go to other pages, searching, etc). Actually, I want to use different token every time I get data using ajax request on datatable because there is token validation on server side which is check whether token is expired or not. So I need to get new token first before doing ajax request to get data. Do you have idea about it?
1

This works for me:

dataTable.context[0].ajax.data.yourCustomValue = value;

Since my variable name is bwsValue:

var dataTable = $('#users-grid').DataTable( {
    "dom": 'lrtip',
    "order": [[ 0, "asc" ]],
    "processing": true,
    "serverSide": true,
    "ajax":{
        url :"users_list.php?active="+active,
        "data": {
            "bwsValue": 1
        },
        type: "post",
    }
});

I can now set the data to:

dataTable.context[0].ajax.data.bwsValue = 2;

Comments

-1

You do not want to do a async request in this case, so instead of using $.get try something like this (async:false):

$.ajax({
    type: "GET",
    async:false,
    url: "/User/GetToken?_=" + new Date().getTime(),
    success: function(token, textStatus, xhr) {
        data.token = token;
    }
});

5 Comments

Why not async? He can always chain the calls.
sure he can, but if he doesn't want to rewrite the whole ting async:false will work.
Yes it will work, but is async not a better design as it will not block the user thread.
This is an absolutely horrible "solution". It solves a beginners lack of understanding of the asynchronous execution flow (no offense, we have all been there!) by making the code even more hackish.
Hehe....wow..quite a feedback. Relax..I do know async execution very well. I have apparently misunderstood the problem. But now I've learned my lesson..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.