Can't get JSON data to show using JS object variable; works with AJAX

Can't get JSON data to show using JS object variable; works with AJAX

Bob RodesBob Rodes Posts: 17Questions: 1Answers: 0

I've been tinkering with Allan's example to show inline child data in a table, with the +/- button. I'm able to get it to work with my own data using ajax if I access it from a text file. However, I can't seem to access exactly the same data from a javascript variable. I have the problem set up here: http://live.datatables.net/xaduruni/1/watch?html,js,output

Here's the relevant successful code:

            var table = $('#example2').DataTable( {
                "ajax": 'json.txt',
                "columns": [
                    {
                        "className":      'details-control',
                        "orderable":      false,
                        "data":           null,
                        "defaultContent": ''
                    },
                    { "data": "ID" },
                    { "data": "CAGE" },
                    { "data": "Name" }
                ],
                "order": [[1, 'asc']]
            } );

The contents of json.txt are:

{
  "data": [
    {
        "ID": "6",
        "Name": "Nocturnal Aviator Electronics",
        "CAGE": "ZZZZZ",
        "Type": "B",
        "City": "Wartrace, TN",
        "POC": "Bob Rodes",
        "phone": "123-234-3458",
        "fax": "123-234-8765",
        "Mem": "Y",
        "NSNs": "0",
        "RFQs": "0",
        "OD": "3"
    }
  ]
}

Now, when I change the above code to put the contents of json.txt into an object variable, I get no records. I don't see anything in the doc that says I can't do this (in fact it says I can), so I must be doing something wrong. Can someone explain?

TIA

Bob

Replies

  • Tom (DataTables)Tom (DataTables) Posts: 139Questions: 0Answers: 26

    Hi Bob

    I believe this should fix it.

    I changed
    "data": testdata,
    to
    "data": testdata.data,

    Full snippet below

      var table = $('#example2').DataTable( {
                    "data": testdata.data,
                    "columns": [
                        {
                            "className":      'details-control',
                            "orderable":      false,
                            "data":           null,
                            "defaultContent": ''
                        },
                        { "data": "ID" },
                        { "data": "CAGE" },
                        { "data": "Name" }
                    ],
                    "order": [[1, 'asc']]
                } );
    
  • Bob RodesBob Rodes Posts: 17Questions: 1Answers: 0
    edited May 2016

    And there's my data! Fascinating. Thanks a lot! After looking a little deeper, I can see why we have to refer to the wrapper data object here, although why we don't have to with the ajax/json file call (which of course we couldn't really: I can't see where ajax: 'json.txt'.data is anything remotely like correct syntax) is a bit obscure to me. Perhaps you have some insight on that you can share.

    I'm presently using PHP calls to get data in object variables, pass them directly into JS object variables, and pass those into DataTableI() calls. I'm working to get Allen's AJAX-based example to run this way. Now, the PHP data in the call is a simple array of objects, in [ {},{},{etc} ] format. This format appears to require that we wrap that in another object: {data:[ {},{},{etc} ] }. I couldn't get any of my test examples of my own data to work until I did this, anyway. Is this required because of the way the child data are set up? Here's Allen's code to show the children:

        // Add event listener for opening and closing details
        $('#example tbody').on('click', 'td.details-control', function () {
            var tr = $(this).closest('tr');
            var row = table.row( tr );
     
            if ( row.child.isShown() ) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
            }
            else {
                // Open this row
                row.child( format(row.data()) ).show();
                tr.addClass('shown');
            }
        } );
    

    In particular, the line row.child( format(row.data()) ).show(); obviously requires the wrapping data object. But I'd like to avoid editing the incoming array in my own app to wrap it if I can. I tried the naive approach of just removing the wrapper, and just using row.child( format(row()) ).show(); which was, well, naive: of course it blew up in spectacular fashion.

    So, is there a way to avoid wrapping the object in the data:{} object, or do I have to have an object within an object to make this work? In any case, thanks a lot for getting me going again.

  • allanallan Posts: 63,212Questions: 1Answers: 10,415 Site admin

    I'm going to step in for just a second and answer your first query, but leave your follow up question to Tom.

    can see why we have to refer to the wrapper data object here, although why we don't have to with the ajax/json file call (which of course we couldn't really: I can't see where ajax: 'json.txt'.data is anything remotely like correct syntax) is a bit obscure to me. Perhaps you have some insight on that you can share.

    The wrapper object when getting the data via Ajax is a legacy decision of mine. It was (and still use) useful to allow the JSON to carry more than just the data needed for the DataTable. However, it is quite possible to change the data array's location, or even to do away with the wrapper object - the ajax.dataSrc option provides that ability.

    Ultimately you just need to get the data array into the table - data does that directly, while ajax provides some mapping options.

    This may or may not answer your follow up question - let us know!

    Allan

  • Bob RodesBob Rodes Posts: 17Questions: 1Answers: 0

    Thanks for your explanation, Allan, that all makes sense. Once I understood what was going on, I found it simple to wrap a the data: object around the incoming data ($rs is the PHP variable containing the JSON data):

                var theData = { "data": <?php echo $rs; ?> } 
                var table = $('#example2').DataTable( {
                    "data": theData.data,
                    [etc.]
    

    This is all very helpful insight, as I have been resorting with other tables to transforming the incoming object data into straight array data. I'll have to go back now and redo that.

This discussion has been closed.