Datatables + SVC => Unable to get property "length"

Datatables + SVC => Unable to get property "length"

rubenduivemanrubenduiveman Posts: 4Questions: 1Answers: 0
edited May 2015 in Free community support

Hi all;

I'm trying to use server-side processing for a datatable (yes, I'm sure I want server-side processing). However, my server-side is a Microsoft web service (mvc). I've configured the OperationContract so that it accepts "get", and returns a JSON string.

My problem is this: the returned JSON is not parsed correctly, for an error is thrown saying "Unable to get property 'length' of undefined or null reference".

Debugging info is available via: http://debug.datatables.net/axedeg.

My svc looks like this:

namespace DataTableTest
{
    public class dtwebservice {

        [OperationContract]
        [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
        public string GetArticles(int start, int length)
        {
            
            DtData r = new DtData();

            r.draw = 1;
            r.recordsTotal = 12;
            r.recordsFiltered = 12;

            r.data.Add(new DtData.DtDataItem("Bert", "Anon", "Development"));
            r.data.Add(new DtData.DtDataItem("Bart", "Van Der Anon", "Development"));
            r.data.Add(new DtData.DtDataItem("Macy", "Anon", "Development"));
            r.data.Add(new DtData.DtDataItem("Sander", "Anon", "Development"));
            r.data.Add(new DtData.DtDataItem("Ruben", "Anon", "Development"));

            r.data.Add(new DtData.DtDataItem("Frank", "Anon", "CEO"));

            r.data.Add(new DtData.DtDataItem("Arjan", "De Anon", "Consultancy"));
            r.data.Add(new DtData.DtDataItem("Paulien", "Anon", "Consultancy"));
            r.data.Add(new DtData.DtDataItem("Orestis", "Anon", "Consultancy"));

            r.data.Add(new DtData.DtDataItem("Malu", "Anon", "Administratie"));
            r.data.Add(new DtData.DtDataItem("Larissa", "Anon", "Marketing"));

            r.data.Add(new DtData.DtDataItem("Diana", "Van Anon", "Services"));
            r.data.Add(new DtData.DtDataItem("Bjorn", "Anon", "Services"));

            return new JavaScriptSerializer { MaxJsonLength = Int32.MaxValue }.Serialize(r);
        }
    }

    public class DtData
    {
        public int draw { get; set; }
        public int recordsTotal { get; set; }
        public int recordsFiltered { get; set; }
        public List<DtDataItem> data { get; set; }

        public DtData()
        {
            this.data = new List<DtDataItem>();
        }

        public class DtDataItem
        {
            public string f2030 { get; set; }
            public string f2031 { get; set; }
            public string f2032 { get; set; }

            public DtDataItem(string f2030, string f2031, string f2032)
            {
                this.f2030 = f2030;
                this.f2031 = f2031;
                this.f2032 = f2032;
            }
        }
    }

My JavaScript (actually TypeScript) looks like this:

window.onload = () => {


    var dtsettings = {
        "processing": true,
        "serverSide": true,
        "ajax": {
            url: "dtwebservice.svc/GetArticles"
        },
        "columns": [
            {
                title: "first name",
                classname: "firstname",
                data: "f2030",
                visible: true
            },
            {
                title: "last name",
                classname: "lastname",
                data: "f2033",
                visible: false
            },
            {
                title: "department",
                classname: "department",
                data: "f2032",
                visible: true
            }
        ]
    };

    $('#example').dataTable(dtsettings);
} 

And my HTML body looks like this (yes, I've loaded all JS and CSS files).

<body>
    <h1>TypeScript, DataTables and Knockout</h1>

    <div id="content">
        <table id="example" class="display" cellspacing="0" width="100%"></table>
    </div>
</body>

This question has an accepted answers - jump to answer

Answers

  • rubenduivemanrubenduiveman Posts: 4Questions: 1Answers: 0
    edited May 2015

    I tried to parse the JSON first, using

    "dataSrc": function (jsondata) { return JSON.parse(jsondata); }

    It does not throw an error anymore, but the data is not loaded in the table: the table displays "No matching records found".

  • rubenduivemanrubenduiveman Posts: 4Questions: 1Answers: 0

    I've decided to go full websocket. Using this method, a regular webservice meethod could also be called. In the settings, an "ajax" object has to be present or the fnServerData won't be called. In the fnServerData, it is possible to return whatever you want to the fnCallback, as long as it is an object looking like this:

    {
        data: [ ]
    }
    

    And this is my configuration (simplified example) in TypeScript:

            var dtsettings: any = {
                "processing": true,
                "serverSide": true,
                "ajax": "doesntMatter/IsNotUsed",
                "fnServerData": function (sSource, aoData, fnCallback) {
                    var ws = new WebSocket("wss://url.to/websocket");
    
                    ws.onmessage = function (d) {
                            fnCallback(d);
                    }
    
                    ws.send(JSON.stringify{
                        messageType: Communication.messageTypes.GETDATA,
                        data: aoData
                    }});
    
                }
            };
    
            //initialize the datatable
            var dt = $('#table').DataTable(dtsettings);
    
  • allanallan Posts: 61,798Questions: 1Answers: 10,115 Site admin
    Answer ✓

    Thanks for the debug trace - it shows that a string is being returned, not a JSON object. Can you modify your server-side script to return the string unquoted - that would be the easiest and possibly best fix.

    Allan

This discussion has been closed.