Ajax Call with New API give Sys Parameter Count err; Old API works fine

Ajax Call with New API give Sys Parameter Count err; Old API works fine

JGiuntaJGiunta Posts: 3Questions: 1Answers: 0

All,

Having trouble with the 'ajax' namespace with DataTables 1.10.7. I can issue a native Ajax call fine, but when I use the DataTables API I get a Sys.ParameterCountException.

If I use the old API, it works fine.

Here is an example which works fine:

    $.ajax({
        type: 'POST'
        , url: 'ExpBudgetEmploye.aspx/GetEmployeSummaryAlt'
        , contentType: 'application/json;'
        , data: String.format("{{'DataSource': '{0}' }}", _dbId);
        , dataType: 'json'
        , success: function (data) {
            alert(data.d[0].EmpName);
        }
    });

And using the old API which works fine:

oTable = $('#tblEmployeSummary').DataTable({
        'processing': true
        , 'serverSide': true
        , 'jQueryUI': true
        , 'ordering': false
        , 'paging': false
        , 'scrollCollapse': true
        , 'scrollY': '200px'
        , 'scrollX': '100%'
        , 'sAjaxSource': 'ExpBudgetEmploye.aspx/GetEmployeSummaryAlt'
        , 'sAjaxDataProp': 'd'
        , 'columns': [
            { "title": "EmpName", "data": "EmpName", "type": "string", "className": "EmpName" }
            , { "title": "EmpNumber", "data": "EmpNumber", "type": "string", "className": "EmpNumber" }
            , { "title": "JobCode", "data": "JobCode", "type": "string", "className": "JobCode" }
            , { "title": "HireDate", "data": "HireDate", "type": "date", "className": "HireDate" }
        ]
        , 'fnServerData': function (sSource, aoData, fnCallback) {
                    $.ajax({
                        'dataType': 'json'
                        , 'contentType': 'application/json;'
                        , 'type': 'POST'
                        , 'url': sSource
                        , 'data': String.format("{{DataSource: '{0}' }}", _dbId)
                        , 'success': fnCallback
                    });
                }
    });

But using the new 1.10 way, I get an error. Has anyone had similar trouble?

Here is the code I am using with the new API, which gives me the sys parameter count exception.

oTable = $('#tblEmployeSummary').DataTable({
        'processing': true
        , 'serverSide': true
        , 'jQueryUI': true
        , 'ordering': false
        , 'paging': false
        , 'scrollCollapse': true
        , 'scrollY': '200px'
        , 'scrollX': '100%'
        , 'ajax': ({
            type: 'POST'
            , url: 'ExpBudgetEmploye.aspx/GetEmployeSummaryAlt'
            , contentType: 'application/json;'
            , data: String.format("{{'DataSource': '{0}' }}", _dbId)
            , dataType: 'json'
            , dataSrc: 'd'
        })
        , 'columns': [
            { "title": "EmpName", "data": "EmpName", "type": "string", "className": "EmpName" }
            , { "title": "EmpNumber", "data": "EmpNumber", "type": "string", "className": "EmpNumber" }
            , { "title": "JobCode", "data": "JobCode", "type": "string", "className": "JobCode" }
            , { "title": "HireDate", "data": "HireDate", "type": "date", "className": "HireDate" }
        ]
    });

Answers

  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin

    Can you link to the page so I can debug it please? I presume the String.format("{{'DataSource': '{0}' }}", _dbId) stuff just resolves to a simple string, Or is it a JSON string or something else? It might be that you need to use ajax.data as a function to add data to the object that DataTables sends.

    Allan

  • JGiuntaJGiunta Posts: 3Questions: 1Answers: 0

    Yes what I am passing into ajax.data is just resolves to "{ 'DataSource': '46' }". In this case the page method is expecting one argument. Just for simplicity the page method is:

    Yes what I am passing into ajax.data is just resolves to "{ 'DataSource': '46' }".  In this case the page method is expecting one argument.  In fact for my playing around with this I an not actual using the DataSource argument, I'm just trying to pass something in to see if I can get it working.  The real method will take a number of different parameters.
    
    For simplicity the page method is:
    
        [WebMethod(EnableSession = true)]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
        public static List<EmployeSummary> GetEmployeSummaryAlt(String DataSource) {
    
                List<EmployeSummary> empRecs = new List<EmployeSummary>();
                empRecs.Add(new EmployeSummary(" Name 1", "01", "ABC", new DateTime()));
                empRecs.Add(new EmployeSummary(" Name 2", "02", "DEF", new DateTime()));
                empRecs.Add(new EmployeSummary(" Name 3", "03", "GHI", new DateTime()));
                return empRecs;
        }
    

    I get back an EmployeSummary object filled in.

    Stepping through jquery.dataTables.js I found that I had ajax.data up to a point and then it was gone. I think I tracked it down to around line 2275. Specifically when data is set to either newData or the $.extended data. That IF returns and empty object with no useful properties. So the $.extend() is not doing what it should be doing correctly. I haven't futzed around with jQuery in quite some time an I need to re-familiarize myself with what exactly $.extend() does.

    I "fixed" it by just adding a line underneath that says data = newData, but I realize I probably messed something else up with this hack.

    From jquery.dataTables.js around line 2275:

        if ($.isPlainObject(ajax) && ajax.data) {
            ajaxData = ajax.data;
    
            var newData = $.isFunction(ajaxData) ?
                ajaxData(data, oSettings) :  // fn can manipulate data or return
                ajaxData;                      // an object object or array to merge
    
            // If the function returned something, use that alone
            
            // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
            //--> At this point ajaxData and newData = "{ 'DataSource': '46' }" 
            //      which is what I want.
            //--> Below $.isFunction evaluates to FALSE. 
            //      newData evaluates to True, so I fall into the ELSE path.
            // --> the $.extend ends up being:
                -       $.extend(true, data, newData);  {...}   Object
                    +       [Methods]   {...}   
                    +       [prototype] {...}   Object
            // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
            
            data = $.isFunction(ajaxData) && newData ?
                newData :
                $.extend(true, data, newData); 
    
            data = newData; //<-- My hacky "fix".  
            //--> I need data to contain the arguments
            //      that are passed to the page method.
    
            // Remove the data property as we've resolved it already and don't want
            // jQuery to do it again (it is restored at the end of the function)
            delete ajax.data;
        }
    
        var baseAjax = {
                "data": data, //<-- Without my change 'data' is nothing  useful
                              //     and I get the parameter count exception.
                "success": function (json) {
                    var error = json.error || json.sError;
                    if (error) {
                        _fnLog(oSettings, 0, error);
                    }
    
                    oSettings.json = json;
                    callback(json);
                },
                "dataType": "json",
                "cache": false,
                "type": oSettings.sServerMethod,
                "error": function (xhr, error, thrown) {
                    var ret = _fnCallbackFire(oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR]);
    
                    if ($.inArray(true, ret) === -1) {
                        if (error == "parsererror") {
                            _fnLog(oSettings, 0, 'Invalid JSON response', 1);
                        }
                        else if (xhr.readyState === 4) {
                            _fnLog(oSettings, 0, 'Ajax error', 7);
                        }
                    }
    
                    _fnProcessingDisplay(oSettings, false);
                }
            };
    
  • JGiuntaJGiunta Posts: 3Questions: 1Answers: 0

    If I change my ajax.data property to a function it works. Still don't understand why the $.extend is not merging the two objects properly though.

        oTable = $('#tblEmployeSummary').DataTable({
            "processing": false
            , "serverSide": false
            , "jQueryUI": true
            , "ordering": false
            , "paging": false
            , "scrollCollapse": true
            , "scrollY": '200px'
            , "scrollX": '100%'
            , "ajax": ({
                "type": 'POST'
                , "url": 'ExpBudgetEmploye.aspx/GetEmployeSummaryAlt'
                , "contentType": 'application/json;'
                //, "data": String.format("{{'DataSource': '{0}' }}", _dbId) //--> Will not work
                , "data": function () { return String.format("{{'DataSource': '{0}' }}", _dbId); } 
                   // above works fine.
                , 'dataSrc': 'd'
            })
            , 'columns': [
                { "title": "EmpName", "data": "EmpName", "type": "string", "className": "EmpName" }
                , { "title": "EmpNumber", "data": "EmpNumber", "type": "string", "className": "EmpNumber" }
                , { "title": "JobCode", "data": "JobCode", "type": "string", "className": "JobCode" }
                , { "title": "HireDate", "data": "HireDate", "type": "date", "className": "HireDate" }
            ]
        });
    
    
  • allanallan Posts: 63,692Questions: 1Answers: 10,500 Site admin

    Because $.extend expects an object, but it looks like you are giving it a string. If you added JSON.parse( ... ) to get an object from your string it would probably work.

    Allan

This discussion has been closed.