Datatable 'loading' when calling data from asmx using ajax

Datatable 'loading' when calling data from asmx using ajax

madlukamadluka Posts: 3Questions: 1Answers: 0

I have an .asmx WebService that spits out valid JSON (using the serializer). Here's my code for two Datatables, the first Datatable works perfectly but as I understand it, using an Ajax success function to make the datatable is not the way to do things. So the second chunk of code is my attempt to get Datatables to make the ajax call, and the debugger shows the response coming back exactly the same as the first table, but no data gets rendered in the table - just "Loading".

    $.ajax({
        type: "POST",
        url: "../../scripts/sqlservice.asmx/GetData",
        contentType: "application/json; charset=utf-8",
        success: function (data) {
            $('#all_systems').dataTable({
                data: JSON.parse(data.d),
                columns: [
                    { "data": "Netbios_Name0" },
                    { "data": "Resource_Domain_OR_Workgr0" },
                    { "data": "User_Name0" }
                ]
            });
        },
        failure: function (data) {
            alert(error);
        }
    });

    $('#all_systems2').DataTable({
        ajax: {
            type: "POST",
            url: "../../scripts/sqlservice.asmx/GetData",
            contentType: "application/json; charset=utf-8",
            success: function (data) {
                alert(data.d); // EVERYTHING IS WORKING AT THIS POINT AND I HAVE A VALID JSON STRING RETURNED
                data = JSON.parse(data.d); // SO I PARSE THE STRING AS I DO IN THE DATATABLE ABOVE

                // AM I NOW MISSING SOMETHING HERE TO GET THE JSON PARSED DATA INTO THE DATATABLE?
            },
            failure: function (data) {
                alert(error);
            }
        },
        columns: [
            { "data": "Netbios_Name0" },
            { "data": "Resource_Domain_OR_Workgr0" },
            { "data": "User_Name0" }
        ]
    });

At this point in time, I am not interested in ServerSide processing as the number of rows returned should be fine for client-side processing.

What am I missing?! Thanks!

This question has an accepted answers - jump to answer

Answers

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75
    edited November 2015

    Uhm... I see you're using the ajax as the same thing as $.ajax from jQuery... Im pretty sure htats not right... Meaning I dont think the ajax.contentType, ajax.success and ajax.failure would work properly...

    Does the console log show anything?..

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75
    Answer ✓

    I would think this should work.. But obviously I havent tested it in your network..

    $('#all_systems2').DataTable({
        ajax: {
            type: "POST",
            url: "../../scripts/sqlservice.asmx/GetData",
            dataSrc: 'd'
        },
        columns: [
            { "data": "Netbios_Name0" },
            { "data": "Resource_Domain_OR_Workgr0" },
            { "data": "User_Name0" }
        ]
    });
    

    You dont need contentType: "application/json; charset=utf-8", and you certainly don't need the success or failure (Which I thought it was error, not failure

    I notice you were parsing data.d in the first example, so since d is the object that holds the data (The default is data, we use ajax.dataSrc to specify that it is d.

    So as long as the source of ajax.url looks something like this:

    {
      "d": [
        {
          "Netbios_Name0": "Some Name 1",
          "Resource_Domain_OR_Workgr0": "Some Domain 1",
          "User_Name0": "Some User 1"
        },
        {
          "Netbios_Name0": "Some Name 2",
          "Resource_Domain_OR_Workgr0": "Some Domain 2",
          "User_Name0": "Some User 2"
        }
      ]
    }
    

    You should be fine..

  • madlukamadluka Posts: 3Questions: 1Answers: 0
    edited November 2015

    Thanks for your quick responses!

    OK, so I think I've been here before... without the contentType option the asmx webservice returns as text/html which is no good to us and the Datatable errors stating invalid JSON and the debugger confirms the response body as wrapped up in xml.
    So, I added the contentType option and now I get an error "Requested unknown parameter 'Netbios_Name0' for row 0. I end up with a table full of NULL.

    "d" is something that apparently, so I have read, gets spat out instead of "data" by default when you use asmx/webservice as an AJAX source. The sqlservice.asmx I am using uses this function to spit out the data...

        Public Shared Function GetJson(ByVal dt As DataTable) As String
            Dim serializer As New System.Web.Script.Serialization.JavaScriptSerializer()
            serializer.MaxJsonLength = Integer.MaxValue
    
            Dim rows As New List(Of Dictionary(Of String, Object))()
            Dim row As Dictionary(Of String, Object) = Nothing
            For Each dr As DataRow In dt.Rows
                row = New Dictionary(Of String, Object)()
                For Each dc As DataColumn In dt.Columns
                    row.Add(dc.ColumnName.Trim(), dr(dc))
                Next
                rows.Add(row)
            Next
            Return serializer.Serialize(rows)
        End Function
    

    Here's what the code for the second table now looks like...

            $('#all_systems2').DataTable({
                ajax: {
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: "../../scripts/sqlservice.asmx/GetData",
                    dataSrc: 'd'
                },
                columns: [
                    { "data": "Netbios_Name0" },
                    { "data": "Resource_Domain_OR_Workgr0" },
                    { "data": "User_Name0" }
                ]
            });
    

    I used the debugger to look at the response body and it is laid out exactly as you have in your source example above, which is exactly the same response body received by my first functional Datatable code, which validates using JSONLint...

    {"d":"[{\"Netbios_Name0\":\"MCH11002\",\"Resource_Domain_OR_Workgr0\":\"CONTOSO.COM\",\"User_Name0\":\"john.doe\"},{\"Netbios_Name0\":\"MCH11003\",\"Resource_Domain_OR_Workgr0\":\"CONTOSO.COM\",\"User_Name0\":\"mike.smith\"}]"}
    

    Like you say, it SHOULD work, the data format is good (as the previous datatable eats up the same response body)... and yet...

    Thanks!

  • jLinuxjLinux Posts: 981Questions: 73Answers: 75

    Ill write something up when i get home, but you can use the xhr to output some data for troubleshooting..

  • madlukamadluka Posts: 3Questions: 1Answers: 0

    Hurrah! With your help and some experimentation I figured it out! The last hurdle was that using my asmx web service we must always use JSON.parse on the returned data. After fishing around in the Datatables support I found this help page https://datatables.net/reference/option/ajax.dataSrc which mentioned how to use a function to manipulate the data returned from the server and that did the trick!
    Here is my working second datatable code...

            $('#all_systems2').DataTable({
                ajax: {
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    url: "../../scripts/sqlservice.asmx/GetData",
                    dataSrc: function (json) {
                        return JSON.parse(json.d)
                    }
                },
                columns: [
                    { data: "Netbios_Name0" },
                    { data: "Resource_Domain_OR_Workgr0" },
                    { data: "User_Name0" }
                ]
            });
    

    Many thanks for your help! I will sleep tonight!

This discussion has been closed.