garuda one
garuda one

Reputation: 131

Is my ajax-sourced DataTable not parsing correctly?

Let's start with the error I'm getting...

DataTables warning: tableid=myTable - Requested
unknown parameter 'Name' for row 0, column 0. For more
information about this error, please see http://datatables.net/tn/4

I've run the JSON response through jsonlint to verify its validity, and inspected it to check that both the data properties exist and are non-null (so it's not an issue of needing defaultContent). Here is the relevant code:

HTML

<table id="myTable" name="myTable" class="table table-hover">
    <thead>
        <tr>
            <th>Submitter</th>
            <th>Submit Date</th>
            <th>Is Restricted</th>
            <th>Libraries</th>
            <th>RequestID</th>
        </tr>
    </thead>
</table>

JS

var table = $("#myTable").DataTable({
    ajax: {
        url: "MyPage.aspx/GetRequests",
        dataSrc: "d",
        type: "POST",
        contentType: "application/json; charset=utf-8"
    },
    columns: [
        { data: "Name", name: "submitter" },
        { data: "SubmitDate", name: "submit-date" },
        { data: "IsRestricted", name: "is-restricted" },
        { data: "Libraries", name: "libraries" },
        { data: "RequestID", name: "request-ID" }
    ],
    info: false,
    paging: false,
    searching: false,
    select: "single"
});

dataSrc: "d" is for the property to read in the response:

as a nested property d of the response

And here is a snippet of the JSON response:

{"d":"[{
    \"RequestID\":50,
    \"Status\":0,
    \"Libraries\":
        [{\"l_id\":0,
        \"library_name\":\"Cat Books\",
        \"request_id\":50,
        \"action\":0,
        \"action_by\":null,
        \"granted_by\":null,
        \"action_date\":\"\\/Date(1488475446477)\\/\"},
        {\"l_id\":0,
        \"library_name\":\"Dog Books\",
        \"request_id\":50,
        \"action\":0,
        \"action_by\":null,
        \"granted_by\":null,
        \"action_date\":\"\\/Date(1488475446477)\\/\",
        }],
    \"Name\":\"Alshon Jeffrey\",
    \"Department\":null,
    \"SubmitDate\":\"\\/Date(1488475446477)\\/\",
    \"IsRestricted\":true}]"}

The table (after the error alerts twice), looks like this:

all null cells

I've tried nulling the Libraries property to make sure DataTables isn't trying to parse that collection into the table, same error. Is the d in the response still throwing DataTables off? Or is the table structure not right? I tried adding a tbody placeholder with no luck, and again with tbody > tr > td placeholders. I'm pretty much out of ideas at this point...

In case it matters, this is with asp.net webforms and a [WebMethod] using a JavaScriptSerializer.

EDIT

Here's the server side code I use to produce the JSON. I've tried JavaScriptSeralizer and JsonConvert, both methods seem to me to produce the same JSON, and the JSON in the response for both is in d:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string GetRequests()
{
    var requests = DataGetter.GetRequests().OrderBy(r => r.SubmitDate).ToList();

    return new JavaScriptSerializer().Serialize(requests);

    // Have also tried:
    // return JsonConvert.SerializeObject(requests);
}

Upvotes: 0

Views: 378

Answers (1)

Bindrid
Bindrid

Reputation: 3735

My first advice, dump the JavaScriptSerializer in favor of NewtonSoft serializer. It's free, does a better job is probably already included if you are using visual studio 15.

Here is what my web method looks like starting with my data structure:

public class wsService : System.Web.Services.WebService
{

    public struct dtData
    {
        public string name;
        public string position;
        public Int32 salary;
        public string start_date;
        public string office;
        public string extn;
    }

    [WebMethod]
    public string GetDTDataSerializedList(string parameters)
    {
        return JsonConvert.SerializeObject(getDataTableData());
    }

    private List<dtData> getDataTableData()
    {
        List<dtData> dataList = new List<dtData>();
        dtData item = new dtData();

        item.name = "Tiger Nixon";
        item.position = "System Architect";
        item.salary = 320800;
        item.start_date = "2011/04/25";
        item.office = "Edinburgh";
        item.extn = "5421";
        dataList.Add(item);
      //blah blah blah more objects added then return
      // I hard coded the data just for testing and dev
        return dataList;
    }
}

The above is probably similar to yours. I don't use the dataSrc. Instead I use the dataFilter section to put the data in a form that DataTables expect. Here is the relevant part of the data tables:

var table = $('#example').DataTable({
            'processing': false,
            // Again, this code will not work if serverSide is set to true.
            'serverSide': false,
            'ajax': {
                // I used an asmx page in my own development environment to get the data.
                url: 'wsService.asmx/GetDTDataSerializedList',
                type: "post",
                data: function (dtparms) {
                    return JSON.stringify({
                        parameters: JSON.stringify(dtparms)
                    });
                },
                contentType: "application/json; charset=utf-8",

                // dtData is what has been returned in the server
                dataFilter: function (dtData) {
                    // I parse it so I can get to the data in "d"
                    var p = JSON.parse(dtData);
                    // the data inside the d is also serialized 
                    // so I have to parse it out a second time
                    var d = JSON.parse(p.d);
                    j

                    // then reserialize and return it in a form
                    // that datatables likes.
                    return JSON.stringify({
                        data: d
                    });
                },
            },

Upvotes: 1

Related Questions