DT Can't get data from an Object inside an array inside an Object.

DT Can't get data from an Object inside an array inside an Object.

SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
edited November 2015 in Free community support

Okay, So i've been attempting to get data from this array, But its just not working :/
I'm sure i'm missing something simple again, But i thought i would put it out there.

The Broken Goodies:

<script>        
$(document).ready(function() {
    $('#example').DataTable( {
        "ajax":{
        "url":"http://gaming.adduce.co.nz:8888/getPlayerKillsHistory?ids=76561198061378579",
        "cache": true,
        "dataSrc": "PlayersKillsHistory"},
        "searching":false,
        "paging":false,
        "processing": true,
    columns: [
        { data: 'PlayersKillsHistory.76561198061378579.deaths.dateTime' },
        { data: 'PlayersKillsHistory.76561198061378579.deaths.idKiller' },
        { data: 'PlayersKillsHistory.76561198061378579.deaths.killerName' }
    ]
    });});
</script>
  
<table id="example" class="display" width="100%">
<thead><tr>
<th>Killers SteamID</th><th width="200px">Name</th><th>Date/Time</th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<th>Killers SteamID</th><th width="200px">Name</th><th>Date/Time</th>
</tr></tfoot>
</table>

I have tried to get the data using:

PlayersKillsHistory.76561198061378579.deaths.dateTime
76561198061378579.deaths.dateTime
deaths.dateTime

I've tried changing dataSrc to:

PlayersKillsHistory.76561198061378579
76561198061378579

I'm stuck :( I've tried the recommendations in all of the examples to no avail.

Answers

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2

    Data Returned By Endpoint i'm trying to read:

    {
        "PlayersKillsHistory": [
            {
                "76561198061378579": {
                    "deaths": [
                        {
                            "dateTime": "1447039478215",
                            "idKiller": "76561198040013930",
                            "killerName": "Liam"
                        },
                        {
                            "dateTime": "1447039408964",
                            "idKiller": "76561198040013930",
                            "killerName": "Liam"
                        }
                    ],
                    "kills": [
                        {
                            "dateTime": "1447140138178",
                            "idKilled": "76561198055782576",
                            "killedName": "monolith"
                        },
                        {
                            "dateTime": "1447126200078",
                            "idKilled": "76561198039472062",
                            "killedName": "lyfsdeath"
                        }
                    ]
                }
            }
        ]
    }
    
  • aaronwaaronw Posts: 89Questions: 3Answers: 4

    So you have to watch out on the [] vs {} in JSON. It's kind of obtuse. Basically anything in [] is an Array, and then inside the {} is an object. Look at http://www.w3schools.com/json/json_syntax.asp to see if you can unwrap it. on the DT side look at http://datatables.net/examples/ajax/objects_subarrays.html and http://datatables.net/examples/ajax/deep.html and http://datatables.net/reference/option/ajax

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    I have already followed those examples, That is why i am where i am, I am still having problems retrieving the data with DT, I can get the data numerous ways if i don't want to use DT by simply stringifying it.

    I have tried to retrieve it as an object.
    I have tried to retrieve it as an array
    I have tried to retrieve it as a sub-array.
    I have followed every ajax related example on this entire website.
    I have created variations of every single ajax example on this website.
    

    I am asking for a DT specific solution because i feel like its my novice understanding of DT that is the problem.

    That w3schools link is completely irrelevant for JSON nested this deep and in this manner, It is compliant JSON, It just doesn't seem to be readable with DT. I was considering becoming a supporter because i really appreciate what DT does, But i'm thinking this solution can't do what i want without getting un-necessarily complicated.

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    Would really like some constructive help with this,

    I've been enjoying the simplicity of DT so far..

  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin

    You need to give the array of data to DataTables as an array - it does not accept objects there. Specifically PlayersKillsHistory is an object - DataTables will not accept that as the source for the rows. The data for each row can be an object no problem, but it must be an array that contains them.

    You can use ajax.dataSrc as a function to convert from the object to an array. $.each for example could be used.

    Allan

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    Thanks for the response allan, Extremely helpful!

    Are there examples of dataSrc as a function anywhere?

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    Could i do something simple like...

    <script>       
    $(document).ready(function() {
        $('#example').DataTable( {
            "ajax":{
            "url":"http://gaming.adduce.co.nz:8888/getPlayerKillsHistory?ids=76561198061378579",
            "cache": true,
            "dataSrc": function (json) {var return_data = new Array();};,
        columns: [...]
    </script>
    
  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin

    Not in the live examples actually - that is probably one I should add. There is an example in the ajax.dataSrc documentation (last example on the page).

    Something like:

    dataSrc: function ( json ) {
      return $.map( json.PlayersKillsHistory, function ( el, key ) {
        el.id = key;
        return el;
      };
    }
    

    Uses $.map to get the array. I've not tested the above, but I think it should work okay... :-)

    Allan

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    /removed/

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    /removed/

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    / removed /

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    / Removed /

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015
    <script>        
    $(document).ready(function() {
        $('#example').DataTable( {
            "ajax":
            
        {
            "url":"http://gaming.adduce.co.nz:8888/getPlayerKillsHistory?ids=76561198061378579",
            "cache": true,
            "dataSrc": function (json) {
          var return_data = new Array();
          for(var i=0;i< json.length; i++){
            return_data.push()
          }
          console.log (json);
          return return_data;
    }
      },
      "columns"    : [
        {'data': 'PlayersKillsHistory.PlayersKillsHistory.76561198061378579.deaths.idKiller'},
        {'data': 'PlayersKillsHistory.PlayersKillsHistory.76561198061378579.deaths.dateTime'},
        {'data': 'PlayersKillsHistory.PlayersKillsHistory.76561198061378579.deaths.killerName'}
        ]
        });});
        
    </script>
    

    Okay, So i was able to turn PlayersKillsHistory into an Array, But now i'm having trouble getting the data into the columns. The screenshot below shows the structure.

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015
    View post on imgur.com

    Using the above code, I can get the array, But i still don't know how to get it into the columns.

  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin
    data: 'deaths.killerName'
    

    for the column to display the killer table. etc for the other columns.

    No need for all the PlayersKillsHistory.PlayersKillsHistory.76561198061378579 stuff - since the data object for each row has already been resolved.

    See also the data manual.

    Allan

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    I have changed it as you have suggested, But its just saying "No data available in table"

    Workable version:

    <html>
    <head>
    
    <script type="text/javascript" src="https://cdn.datatables.net/s/dt/jq-2.1.4,dt-1.10.10/datatables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/s/ju/dt-1.10.10/datatables.min.css"/>
     </head>
     <body>
    <script>       
    $(document).ready(function() {
        $('#example').DataTable( {
            "ajax":
             
        {
            "url":"http://gaming.adduce.co.nz:8888/getPlayerKillsHistory?ids=76561198041352960",
            "cache": true,
            "dataSrc": function (json) {
          var return_data = new Array();
          for(var i=0;i< json.length; i++){
            return_data.push()
          }
          console.log (json);
          return return_data;
    }
      },
      "columns"    : [
        {'data': 'deaths.idKiller'},
        {'data': 'deaths.dateTime'},
        {'data': 'deaths.killerName'}
        ]
        });});
         
    </script>
      
    <table id="example" class="display" width="100%">
    
    <thead>
    <tr>
    <th>Killers SteamID</th><th width="200px">Name</th><th>Date/Time</th>
    </tr>
    </thead>
    
    <tbody></tbody>
    
    <tfoot>
    <tr>
    <th>Killers SteamID</th><th width="200px">Name</th><th>Date/Time</th>
    </tr>
    </tfoot>
    
    </table>
    
    </body>
    </html>
    

    Its returning an array as it should, But datatables can't "find" it ?

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2

    I also just tried:

    <script>       
    $(document).ready(function() {
        $('#example').DataTable( {
            "ajax":
             
        {
            "url":"http://gaming.adduce.co.nz:8888/getPlayerKillsHistory?ids=76561198041352960",
            "cache": true,
            "dataSrc": function (json) {
          var return_data = new Array();
          for(var i=0;i< json.length; i++){
            return_data.push(
            {
              'steamid': deaths.idKiller,
              'date'  : deaths.dateTime,
              'name' : deaths.killerName
            }
            )
          }
          console.log (json);
          return return_data;
    }
      },
      "columns"    : [
        {'data': 'steamid'},
        {'data': 'date'},
        {'data': 'name'}
        ]
        });});
         
    </script>
    

    with no luck, getting rather beside myself with this problem to be honest.

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2

    I also tried the above code with this as a variation:

    return_data.push
    (
      {
      'steamid': json[i].deaths.idKiller,
      'date'  : json[i].deaths.dateTime,
      'name' : json[i].deaths.killerName
      }
    )
    
  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    <script>        
    $(document).ready(function() {
        $('#example').DataTable( {
                "ajax": {
                "dataSrc": function (json) {
                var return_data = [];
                console.log (json);
                return return_data;},
                "url": "http://gaming.adduce.co.nz:8888/getPlayerKillsHistory",
                "data": {ids: '76561198041352960'},
                "cache": true,
            },
            "columns": [
                {'data': 'deaths.idKiller'},
                {'data': 'deaths.dateTime'},
                {'data': 'deaths.killerName'}
            ]
        });
    });
    
        
    </script>
    
    

    As you probably seen by now, I've tried 2 different approaches, which inspired 2 different threads (at different times)

    So.. Why isn't this working.. Looks perfect to me.. The length issue is solved, the array is present, no errors.. but still "No data available in table"

    I have tried so many different ways to get this working, Please help me allan.

  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin
    Answer ✓

    Okay - I didn't know about your other thread on this topic, so I didn't see the fiddle. I understand a bit better now. Do you want the table to show the array of kills for this user? If so, we can massively simplify.

    1. Use ajax.dataSrc to put to the array of data for each row in the table from the JSON - in this case 'PlayersKillsHistory.0.{id}.kills' (replacing {id} as required of course).
    2. Use columns.data to access the data from the objects in that array.

    This simply gives:

        $('#example').DataTable( {
            "ajax": {
                "url": "http://gaming.adduce.co.nz:8888/getPlayerKillsHistory",
                "cache": true,
                "data": { ids: '76561198041352960' },
                dataSrc: 'PlayersKillsHistory.0.76561198041352960.kills'
            },
            "columns": [
                {'data': 'idKilled'},
                {'data': 'dateTime'},
                {'data': 'killedName'}
            ]
        });
    

    http://jsfiddle.net/n3p0mcto/6/

    Allan

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2

    Thank you Allan! That worked great!

    So it always was a simple task :P Knew i could expect simplicity from DT, I should have been more specific about what i was wanting to do.

  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin
    Answer ✓

    We got there in the end :-)

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

    omg. lol. really.

    So PlayersKillsHistory.0.76561198041352960.kills worked.

    I was using PlayersKillsHistory[0].76561198041352960.kills

    Not sure I get why that works. I would think the first one is referencing an object with the . operator.

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    I know how you feel jLinux, The implementation that worked in the end was only .[] Difference to something i had tried earlier in the day.

    But we got there in the end and that is all that counts :P

  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin
    Answer ✓

    So this is an interesting point (for a nerd like me anyway) - the [] notation in columns.render does reference array documentation, but it means that DataTables should concatenate the named properties from the array so they can be displayed in a single cell. Consider for example this data structure:

          "access": [
            {
              "id": "1",
              "name": "Printer"
            },
            {
              "id": "3",
              "name": "Desktop"
            },
            {
              "id": "4",
              "name": "VMs"
            }
          ]
    

    I want to display the name property from the objects in the array in a single cell (this is part of a single row's object) - I'd use access[, ].name - that will concatenate the names separated by ,. So [] is used for array access and display.

    However, .0. works to access a single property from an array because that is how Javascript object notation works. Going again with the JSON just above, if I want to display just the first name from the access array I can use access.0.name.

    You can see that JSON structure used in this Editor example.

    So yes, I can see how it would be confusing and perhaps DataTables should detect an integer in the [] - I can't see why you would ever want to concatenate by an integer, but no doubt that exception would come back to bite at some point as well...

    Allan

  • SamuelNZSamuelNZ Posts: 62Questions: 5Answers: 2
    edited November 2015

    That is interesting insight that will help me in the future i'm sure, Thank you allan!

    You should reword that last post slightly and place it in the documentation somewhere, I'm sure it would be extremely helpful to many!

  • allanallan Posts: 62,296Questions: 1Answers: 10,214 Site admin
    Answer ✓

    Agreed - I was thinking that as I was writing it... Added to the list!

    Allan

This discussion has been closed.