Brian J Brian J - 24 days ago 6
Javascript Question

How to dynamically build a table from a JSON array?

I've placed an AJAX GET call in an Enyo view. The GET calls a web service which returns an array of records including the column headers.

My aim is to dynamically build a table with this returned array, where a row is created for each index and columns for each header within the index.

What I do know in terms of Enyo is to create one record by mapping the AJAX response headers to component fields:

this.$.actionsTaken.setContent( inResponse.ActionsTaken);


But I'm not sure how to do that dynamically and create the table on the fly.

So for example when I inspect the web service response my index 0 contains the following: (Where
ActionsTaken
,
Application
and
EM
are the col headers.)

{
ActionsTaken: "Tested uptime"
Application: "2011 Hanko"
EM: "EM102 "
}


Question:

How can you dynamically build a table from a JSON array?

The AJAX GET:

fetch: function() {
var ajax = new enyo.Ajax({


url: "http://testservice.net/WebService/GetHistory",
async: false,
handleAs:"json",
xhrFields: {withCredentials: true}

});

ajax.go(this.data);
ajax.response(this, "gotResponse");
ajax.error(this, function(inSender, inError) {
Misc.hideMask();
ViewLibrary.back();
Misc.showToast("Error retrieving data");
});

},
gotResponse: function(inSender, inResponse)
{

var debugVar = inResponse;


this.$.actionsTaken.setContent( inResponse.ActionsTaken);
this.$.configurationItemLogicalName_value.setContent( inResponse.Application);
this.$.eM.setContent( inResponse.EM);


},


The components that hold the data values:

{name:"outage_table", kind: "FittableRows",components:[

{content: "Actions Taken", name: "actionsTaken", },
{content: "Application", name: "application", },
{content: "EM", name: "eM", },


]}

Answer

Depending on the complexity of all your data, you might be able to do this fairly simply. Iterate through your array and on each object, you can then iterate through its keys and create each column with its data.

Something like:

for (var k in theObject) {
    // make column k
    // add theObject[k] to it
}

I think the problem is that you have created named components that match this example data, but it is unknown if those will always be the same keys?

There is a kind (enyo.DataTable, which, surprisingly, I have never used) that you might use instead. It lets you add rows (no headers) so you would make your first row from all the object keys, then the next row would be those keys' data. It is derived from DataRepeater so there may be some implementation to work out, such as using an enyo.Collection to store your data and then set the collection to the DataTable.

The other alternative that matches closer to what you have would be to just dynamically create the components as you need them:

this.$.outage_table.createComponents([{...}]);
this.$.outage_table.render(); // need to re-render when dynamically adding components