Search code examples
javascriptarraysdatatablesjavascript-objectstwitch

How do I get DataTables to read nested objects in an array?


I'm trying to get DataTables to read an array containing nested objects, with the data coming from another JSON file. This is part of a freeCodeCamp project.

Using console.log(dataSet) and creating an array manually works perfectly fine but I can't seem to get DataTables to output the data from the dataSet array that has got data pushed from the Twitch.tv API.

HTML:

    <head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Twitch.tv App</title>
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" type="text/css" media="screen" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.css"
/>
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap4.min.js"></script>
<script src="main.js"></script>
    </head>

    <body>
<table id="table" class="table table-striped table-bordered" style="width:100%">
    <thead>
        <tr>
            <th>Channel</th>
            <th>Status</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>

    </tbody>
</table>

    </body>

JS:

    $(document).ready(function () {
var usernames = ["tooshi", "ESL_SC2", "OgamingSC2", "cretetion", "dotademon", "jakenbakelive", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas"];
var dataSet = [];
usernames.forEach(function (username) {
    var apiUrl = "https://wind-bow.glitch.me/twitch-api/streams/"
    apiUrl += username;

    $.getJSON(apiUrl, function (json) {
        var channelUrl = "https://www.twitch.tv/";
        channelUrl += username;
        if (json.stream === null) {
            var status = "Offline";
            dataSet.push({ username, channelUrl, status });
        } else {
            status = "Online";
            var description = json.stream.channel.status;
            dataSet.push({ username, channelUrl, status, description });
        };

    });

});
console.log(dataSet);
$('#table').DataTable({
    data: dataSet,
    columns: [
        { data: "username" },
        { data: "status" },
        { data: "description" }
    ]
});
});

Solution

  • You need to make sure that the dataSet has been populated with all the data from the API. Having a counter and comparing it to the usernames.length is one way.

    counter++;
      if (counter === usernames.length) {
        $('#table').show();
        $('#table').DataTable({
          data: dataSet,
          columns: [{
              data: "username"
            },
            {
              data: "status"
            },
            {
              data: "description"
            }
          ]
        });
      }
    

    Also, make sure the pushed data on dataSet has the same length assigning blank on description can do it.

    if (json.stream === null) {
            status = "Offline";
            description = '';
            dataSet.push({
              username,
              channelUrl,
              status,
              description
            });
          }
    

    JSFiddle