Help with getting AJAX successful response to display records.

Help with getting AJAX successful response to display records.

glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

Description of problem: No error message. Table displays message that "No matching records found".

Network tab shows the call is successful (200) and the response is correct. If I manually apply this same data (no ajax) it works too, so it does not seem to be data structure related.

I have tried the simplest setup here, no filters, searching, etc on the table.

I must be missing something, but I cannot see it. I have looked at the examples and tried to setup something easy based on those. First time setting up with ajax, and a little help here would be greatly appreciated.

    var table = $('#example2').DataTable({
        ajax: {
            url: "@Url.Action("GetAllEvents")",
            type: "POST",
        },
        processing: true,
        serverSide: true,
    });

The data returned looks like this:

{
  "draw": 1,
  "recordsTotal": 3,
  "recordsFiltered": 3,
  "data": [
    {
      "EventId": 3,
      "Occurred": "2024-07-01T06:11:00",
      "StatusName": "Acknowledged",
      "PriorityName": "Low",
      "PriorityName": "Critical",
      "Note": null,
      "Email": "my@email.com",
      "Incident": null,
      "EventHost": "host1",
      "EventMessage": "host1 message",
      "SentBy": "apiclass"
    },
    {
      "EventId": 2,
      "Occurred": "2024-07-01T06:11:00",
      "StatusName": "Closed",
      "PriorityName": "Low",
      "PriorityName": "Critical",
      "Note": null,
      "Email": null,
      "Incident": null,
      "EventHost": "host2",
      "EventMessage": "host2 message",
      "SentBy": "serviceA"
    },
    {
      "EventId": 1,
      "Occurred": "2024-06-01T06:31:00",
      "StatusName": "Open",
      "PriorityName": "Low",
      "PriorityName": "Critical",
      "Note": "This is a test note.",
      "Email": null,
      "Incident": "0000001234",
      "EventHost": "host3",
      "EventMessage": "host3",
      "SentBy": "serviceA"
    }
  ]
}

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887

    You row data are objects not arrays so you need to use columns.data to define the columns. See the data docs for more details and this example.

    Kevin

  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    Corrected a few things above but still no luck.

    I am getting an error message now - 'Cannot read properties of undefined (reading 'length') in the browser. (in the 'for' below from datatables.min.js v2.0.8):

            "ssp" != (i = et(n)) && ("ajax" == i ? At(n, {}, function(t) {
                var e = Lt(n, t);
                for (a = 0; a < e.length; a++)
                    Y(n, e[a]);
                n.iInitDisplayStart = l,
                s(n),
                w(n, !1),
                kt(n)
            }) : (kt(n),
            w(n, !1)))) : setTimeout(function() {
                Et(n)
            }, 200)
    

    Datatable corrected:

        var table = $('#example2').DataTable({
            ajax: {
                url: "@Url.Action("GetAllEvents")",
                type: "POST",
                processing: true,
                serverSide: true,
                columns: [
                    { data: 'EventId' },
                    { data: 'Occurred' },
                    { data: 'StatusName' },
                    { data: 'PriorityName' },
                    { data: 'SeverityName' },
                    { data: 'Note' },
                    { data: 'Email' },
                    { data: 'Incident' },
                    { data: 'EventHost' },
                    { data: 'EventMessage' },
                    { data: 'SentBy' },
                ]
            }
        });
    

    Data corrected:

    {
      "draw": 1,
      "recordsTotal": 3,
      "recordsFiltered": 3,
      "data": [
        {
          "EventId": 3,
          "Occurred": "2024-07-01T06:11:00",
          "StatusName": "Acknowledged",
          "PriorityName": "Low",
          "SeverityName": "Critical",
          "Note": null,
          "Email": "my@email.com",
          "Incident": null,
          "EventHost": "host1 ",
          "EventMessage": "host1 message",
          "SentBy": "apiclass"
        },
        ...(removed for excessive data)
      ]
    }
    
  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    @kthorngren Looks like we were posting about the same time. I did find that and tried as shown above. Now I get an error message per above.

  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887
    edited July 22

    Cannot read properties of undefined (reading 'length')

    Typically this error occurs when the table columns defined in HTML doesn't match the number of columns defined with columns.data. columns.data has 11 columns. How many do you have defined in the -tag thead`?

    To help debug this we will need to see a test case replicating the issue.
    https://datatables.net/manual/tech-notes/10#How-to-provide-a-test-case

    Kevin

  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    I have 11 in the html.

    I will see if I can replicate in a test case.

    <table id="example2" class="table table-sm table-hover  display compact nowrap" style="width:100%">
        <thead>
            <tr>
                <th>ID</th>
                <th>Occurred</th>
                <th>Status</th>
                <th>Priority</th>
                <th>Severity</th>
                <th>Note</th>
                <th>Email</th>
                <th>Incident</th>
                <th>Event Host</th>
                <th>Event Message</th>
                <th>Sent By</th>
            </tr>
        </thead>
    
    </table>
    
    
  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    @kthorngren Here is a test case - https://live.datatables.net/ridaxuru/1/edit

    Not sure if I got it exactly right since I am loading data from a var now but it does recreate the error.

  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887

    You have the data and columns inside the ajax option. I commented out the -option ajaxoption and}` at the end of the Datatables options.
    https://live.datatables.net/vekobede/1/edit

    Looks like you have the same issue with the code above. I didn't notice it before. This also means that the serverSide option is not enabled. I noticed the JSON response has "draw": 1,. Is this hardcoded since server side processing isn't enabled? Its used as a sequence number for the requests. Make sure you are handling as documented in the SSP protocol docs.

    Kevin

  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    @kthorngren ok, feels a bit dumb I did not see that myself.

    I corrected that locally. Now I am back to having no error and "No matching records found" appearing in the table. But the network call for "GetAllEvents" returns my data.

    Maybe I am missing something here, if the data was local or in a variable, I might have something like "data: data.data" as show in the live.datatables linked.

    Am I supposed to specify that somewhere here for the response? Might have misread, but I was sure I read that DataTables handles the success response here.

        var table = $('#example2').DataTable({
            ajax: {
                url: "@Url.Action("GetAllEvents")",
                type: "POST",
            },
            processing: true,
            serverSide: true,
            columns: [
                { data: 'EventId' },
                { data: 'Occurred' },
                { data: 'StatusName' },
                { data: 'PriorityName' },
                { data: 'SeverityName' },
                { data: 'Note' },
                { data: 'Email' },
                { data: 'Incident' },
                { data: 'EventHost' },
                { data: 'EventMessage' },
                { data: 'SentBy' },
            ]
        });
    
  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887

    The JSON response looks correct. The row data is in the expected data object as described in the Ajax docs..

    Is the output you posted from the browser's network inspector?

    Make sure there is no other data in the JSON response. I've seen cases where some text was prefixed to the JSON by the server script.

    If using Chrome there is a Preview tab that will show the data as a Javascript object that you can browse. Does this look correct?

    What happens if you comment out serverSide: true,?

    Paste the Ajax request payload parameters and the JSON response from the browser's network inspector into the thread.

    Possibly there is an event firing that is performing a search. Do you see a second request to the server that might return 0 records?

    I would probably put a debugger breakpoint on the statement after the Datatables initialization to see if the table initially populates then is cleared by something.

    Kevin

  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    @kthorngren - Thank you for your patience and help with this. I'm not opposed to putting in the work but just trying to make sure I did not miss something. This is my first shot using Ajax/Serverside, previous work has generally been in using JavaScript sourced data.

    The data I posted was from the controller returning the data for the ajax call.

    If I edit out "serverSide: true", I get a 200 OK, good response, no payload under Network. But I also get the "TypeError: Cannot read properties of undefined (reading 'length')" in datatables.

    With "serverSide: true", no error.

    I only see 1 event firing, cleared it and checked again, just 1 time.

    Here's the payload:

    draw: 1
    columns[0][data]: EventId
    columns[0][name]: 
    columns[0][searchable]: true
    columns[0][orderable]: true
    columns[0][search][value]: 
    columns[0][search][regex]: false
    columns[1][data]: Occurred
    columns[1][name]: 
    columns[1][searchable]: true
    columns[1][orderable]: true
    columns[1][search][value]: 
    columns[1][search][regex]: false
    columns[2][data]: StatusName
    columns[2][name]: 
    columns[2][searchable]: true
    columns[2][orderable]: true
    columns[2][search][value]: 
    columns[2][search][regex]: false
    columns[3][data]: PriorityName
    columns[3][name]: 
    columns[3][searchable]: true
    columns[3][orderable]: true
    columns[3][search][value]: 
    columns[3][search][regex]: false
    columns[4][data]: SeverityName
    columns[4][name]: 
    columns[4][searchable]: true
    columns[4][orderable]: true
    columns[4][search][value]: 
    columns[4][search][regex]: false
    columns[5][data]: Note
    columns[5][name]: 
    columns[5][searchable]: true
    columns[5][orderable]: true
    columns[5][search][value]: 
    columns[5][search][regex]: false
    columns[6][data]: Email
    columns[6][name]: 
    columns[6][searchable]: true
    columns[6][orderable]: true
    columns[6][search][value]: 
    columns[6][search][regex]: false
    columns[7][data]: Incident
    columns[7][name]: 
    columns[7][searchable]: true
    columns[7][orderable]: true
    columns[7][search][value]: 
    columns[7][search][regex]: false
    columns[8][data]: EventHost
    columns[8][name]: 
    columns[8][searchable]: true
    columns[8][orderable]: true
    columns[8][search][value]: 
    columns[8][search][regex]: false
    columns[9][data]: EventMessage
    columns[9][name]: 
    columns[9][searchable]: true
    columns[9][orderable]: true
    columns[9][search][value]: 
    columns[9][search][regex]: false
    columns[10][data]: SentBy
    columns[10][name]: 
    columns[10][searchable]: true
    columns[10][orderable]: true
    columns[10][search][value]: 
    columns[10][search][regex]: false
    order[0][column]: 0
    order[0][dir]: asc
    order[0][name]: 
    start: 0
    length: 10
    search[value]: 
    search[regex]: false
    

    This is the data from the Response tab under Network:

    "{\r\n  \u0022draw\u0022: 1,\r\n  \u0022recordsTotal\u0022: 3,\r\n  \u0022recordsFiltered\u0022: 3,\r\n  \u0022data\u0022: [\r\n    {\r\n      \u0022EventId\u0022: 3,\r\n      \u0022Occurred\u0022: \u00222024-07-01T06:11:00\u0022,\r\n      \u0022StatusName\u0022: \u0022Acknowledged\u0022,\r\n      \u0022PriorityName\u0022: \u0022Low\u0022,\r\n      \u0022SeverityName\u0022: \u0022Critical\u0022,\r\n      \u0022Note\u0022: null,\r\n      \u0022Email\u0022: \u0022my@email.com\u0022,\r\n      \u0022Incident\u0022: null,\r\n      \u0022EventHost\u0022: \u0022host1\u0022,\r\n      \u0022EventMessage\u0022: \u0022host1 message\u0022,\r\n      \u0022SentBy\u0022: \u0022apiclass\u0022\r\n    },\r\n    {\r\n      \u0022EventId\u0022: 2,\r\n      \u0022Occurred\u0022: \u00222024-07-01T06:11:00\u0022,\r\n      \u0022StatusName\u0022: \u0022Closed\u0022,\r\n      \u0022PriorityName\u0022: \u0022Low\u0022,\r\n      \u0022SeverityName\u0022: \u0022Critical\u0022,\r\n      \u0022Note\u0022: null,\r\n      \u0022Email\u0022: null,\r\n      \u0022Incident\u0022: null,\r\n      \u0022EventHost\u0022: \u0022host2\u0022,\r\n      \u0022EventMessage\u0022: \u0022host2 message\u0022,\r\n      \u0022SentBy\u0022: \u0022ServiceA\u0022\r\n    },\r\n    {\r\n      \u0022EventId\u0022: 1,\r\n      \u0022Occurred\u0022: \u00222024-06-01T06:31:00\u0022,\r\n      \u0022StatusName\u0022: \u0022Open\u0022,\r\n      \u0022PriorityName\u0022: \u0022Low\u0022,\r\n      \u0022SeverityName\u0022: \u0022Critical\u0022,\r\n      \u0022Note\u0022: \u0022This is a test note.\u0022,\r\n      \u0022Email\u0022: null,\r\n      \u0022Incident\u0022: \u00220000001234\u0022,\r\n      \u0022EventHost\u0022: \u0022host3\u0022,\r\n      \u0022EventMessage\u0022: \u0022host3 message\u0022,\r\n      \u0022SentBy\u0022: \u0022ServiceA\u0022\r\n    }\r\n  ]\r\n}"
    

    And just in case, here's the response from the controller:

    {
      "draw": 1,
      "recordsTotal": 3,
      "recordsFiltered": 3,
      "data": [
        {
          "EventId": 3,
          "Occurred": "2024-07-01T06:11:00",
          "StatusName": "Acknowledged",
          "PriorityName": "Low",
          "SeverityName": "Critical",
          "Note": null,
          "Email": "my@email.com",
          "Incident": null,
          "EventHost": "host1",
          "EventMessage": "host1 message",
          "SentBy": "apiclass"
        },
        {
          "EventId": 2,
          "Occurred": "2024-07-01T06:11:00",
          "StatusName": "Closed",
          "PriorityName": "Low",
          "SeverityName": "Critical",
          "Note": null,
          "Email": null,
          "Incident": null,
          "EventHost": "host2",
          "EventMessage": "host2 message",
          "SentBy": "ServiceA"
        },
        {
          "EventId": 1,
          "Occurred": "2024-06-01T06:31:00",
          "StatusName": "Open",
          "PriorityName": "Low",
          "SeverityName": "Critical",
          "Note": "This is a test note.",
          "Email": null,
          "Incident": "0000001234",
          "EventHost": "host3",
          "EventMessage": "host3 message",
          "SentBy": "ServiceA"
        }
      ]
    }
    
  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887
    edited July 22

    I wonder if the problem is due to return "pretty JSON" with the white space, etc. Its valid JSON according to https://jsonlint.com/ but I wonder if it affects how its parsed. It does't seem to process the data structures but sees it as a simple string.

    If you past the string you posted from the Response tab at https://jsonlint.com/ it doesn't format the output. However if you paste the example I posted below the string is formatted when validated. Maybe the same is happening when jQuery is processing the JSON response.

    Can you turn off the formatting of the JSON response so it looks more like this in one line?

    {"draw":1,"recordsTotal":1,"recordsFiltered":1,"data":[{"first_name":"Airi","last_name":"Satou","position":"Accountant","office":"Tokyo","start_date":"28th Nov 08","salary":"$162,700"}]}
    

    FYI its always best to provide us with the JSON response from the browser's network inspector instead of output from the server code.

    Kevin

  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    @kthorngren - Yes, I can do that.

    This does not pass validation at https://jsonlint.com/

    I am assuming that it is due to the Unicode entries for double quotes.

    "{\u0022draw\u0022:1,\u0022recordsTotal\u0022:3,\u0022recordsFiltered\u0022:3,\u0022data\u0022:[{\u0022EventId\u0022:3,\u0022Occurred\u0022:\u00222024-07-01T06:11:00\u0022,\u0022StatusName\u0022:\u0022Acknowledged\u0022,\u0022PriorityName\u0022:\u0022Low\u0022,\u0022SeverityName\u0022:\u0022Critical\u0022,\u0022Note\u0022:null,\u0022Email\u0022:\u0022my@email.com\u0022,\u0022Incident\u0022:null,\u0022EventHost\u0022:\u0022host1\u0022,\u0022EventMessage\u0022:\u0022host1 message\u0022,\u0022SentBy\u0022:\u0022apiclass\u0022},{\u0022EventId\u0022:2,\u0022Occurred\u0022:\u00222024-07-01T06:11:00\u0022,\u0022StatusName\u0022:\u0022Closed\u0022,\u0022PriorityName\u0022:\u0022Low\u0022,\u0022SeverityName\u0022:\u0022Critical\u0022,\u0022Note\u0022:null,\u0022Email\u0022:null,\u0022Incident\u0022:null,\u0022EventHost\u0022:\u0022host2\u0022,\u0022EventMessage\u0022:\u0022host2 message\u0022,\u0022SentBy\u0022:\u0022ServiceA\u0022},{\u0022EventId\u0022:1,\u0022Occurred\u0022:\u00222024-06-01T06:31:00\u0022,\u0022StatusName\u0022:\u0022Open\u0022,\u0022PriorityName\u0022:\u0022Low\u0022,\u0022SeverityName\u0022:\u0022Critical\u0022,\u0022Note\u0022:\u0022This is a test note.\u0022,\u0022Email\u0022:null,\u0022Incident\u0022:\u00220000001234\u0022,\u0022EventHost\u0022:\u0022host3\u0022,\u0022EventMessage\u0022:\u0022host3 message\u0022,\u0022SentBy\u0022:\u0022ServiceA\u0022}]}"
    

    However, if I just make a plain jQuery Ajax call to the same and console log the results, I get the response without the Unicode.

    I cannot see where this is occurring as my method returning this JSON to the controller has it without the Unicode, my controller responds without the Unicode.

    In both cases, the Response tab in the shows both with the Unicode.

    This does pass validation.

    {"draw":1,"recordsTotal":3,"recordsFiltered":3,"data":[{"EventId":3,"Occurred":"2024-07-01T06:11:00","StatusName":"Acknowledged","PriorityName":"Low","SeverityName":"Critical","Note":null,"Email":"my@email.com","Incident":null,"EventHost":"host1","EventMessage":"host1 message","SentBy":"apiclass"},{"EventId":2,"Occurred":"2024-07-01T06:11:00","StatusName":"Closed","PriorityName":"Low","SeverityName":"Critical","Note":null,"Email":null,"Incident":null,"EventHost":"host2","EventMessage":"host2 message","SentBy":"ServiceA"},{"EventId":1,"Occurred":"2024-06-01T06:31:00","StatusName":"Open","PriorityName":"Low","SeverityName":"Critical","Note":"This is a test note.","Email":null,"Incident":"0000001234","EventHost":"host3","EventMessage":"host3 message","SentBy":"ServiceA"}]}
    

    Maybe barking up the wrong tree in regard to that.

    Again, I may be missing something fundamental here. Such as how the data from the response gets applied. I have been assuming that it is handled by DataTables since it handles the response from the call.

  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887
    edited July 22 Answer ✓

    However, if I just make a plain jQuery Ajax call to the same and console log the results, I get the response without the Unicode.

    I get the same if I copy that string into a test case and console.log it:
    https://live.datatables.net/zafukamo/1/edit

    Use the browser's network inspector to see the response from the plain jQuery ajax call.

    I cannot see where this is occurring as my method returning this JSON to the controller has it without the Unicode, my controller responds without the Unicode.

    There must be something at the server that is using unicode when generating the JSON response. What you see in the browser's network inspector is before the JSON gets to Datatables or jQuery ajax. What language is your controller and maybe post the code used to generate the JSON.

    I may be missing something fundamental here. Such as how the data from the response gets applied. I have been assuming that it is handled by DataTables since it handles the response from the call.

    The ajax option uses jQuery ajax() to fetch the data. From the ajax docs:

    object
    Description:
    As an object, the ajax object is passed to jQuery.ajax allowing fine control of the Ajax request. DataTables has a number of default parameters which you can override using this option.

    Kevin

  • glimpsed_chaosglimpsed_chaos Posts: 138Questions: 29Answers: 4

    @kthorngren - Thank you for your assistance Kevin!

    Turns out it was something and that was me JSON serializing or least something in that area.

    I went back to a video that I found to give me a basic usage and they just created a new List<object> on the controller to show a 3-column data structure. Anyways, I mimicked that to ensure I could get their example working for me.

    Then I worked backwards into my code and saw where I could fix this in my repository class. Now it appears in my table and as proper JSON in the Response Network tab.

    Thank you for your time and patience. Hopefully, it was not too much of an inconvenience.

  • kthorngrenkthorngren Posts: 20,991Questions: 26Answers: 4,887
    edited July 23

    feels a bit dumb I did not see that myself.

    I forgot to say that this happens quite often :smile: Its not always easy to see that the options are inside other options.

    Hopefully, it was not too much of an inconvenience.

    Nope, glad you were able to find and fix the problem.

    Kevin

Sign In or Register to comment.