Reputation: 882
I have a JSON file here: https://next.json-generator.com/api/json/get/E1qcwkNxr
and I want to use it to create a table. Using jQuery I get the response Array and map some values to build my table body cells:
var data = $.getJSON('https://next.json-generator.com/api/json/get/E1qcwkNxr', function (response) {
// map JSON to local arrays and define local vars
var rows = response.map(function (r) {
return [
r.age,
r.index,
r.registered,
r.balance,
r.eyeColor
];
});
});
I want to do the same thing with the keys because I want to build the thead cells with that data. There's a way to do it? Object.keys(response[0]);
log me all the keys in the object, How can I map only the key I want to use?
Upvotes: 0
Views: 2894
Reputation: 30893
I would suggest you use $.each()
and not $.map()
. Something like this:
var rows = [];
$.getJSON('https://next.json-generator.com/api/json/get/E1qcwkNxr', function (response) {
$.each(response, function(i, x){
var obj = {};
var s = ["age", "index", "registered", "balance", "eyeColor"];
$.each(x, function(k, v){
if(s.indexOf(k) >= 0){
obj[k] = v;
}
});
rows.push(obj);
});
});
Now you will have a clean array of Objects that has both Keys and Values. You can then use it to build your table.
var $table = $("<table>");
$("<thead>").appendTo($table);
$("<tr>").appendTo($("thead", $table));
$.each(rows[0], function(key, val){
$("<th>").html(key).appendTo($("thead tr", $table));
});
var $tbody = $("<tbody>").appendTo($table);
$.each(rows, function(ind, row){
var $trow = $("<tr>").appendTo($tbody);
$.each(row, function (item){
$("<td>").html(item).appendTo($trow);
});
});
Working Example: https://jsfiddle.net/Twisty/xv4kzy8L/
Update
If you need the the table to display in a specific sort, you can do this with your Array of key names. Then display the results in a specific order:
var headers = ["age", "index", "registered", "balance", "eyeColor"];
var $table = $("<table>");
$("<thead>").appendTo($table);
$("<tr>").appendTo($("thead", $table));
$.each(headers, function(key, val){
$("<th>").html(val).appendTo($("thead tr", $table));
});
var $tbody = $("<tbody>").appendTo($table);
$.each(rows, function(ind, row){
var $trow = $("<tr>").appendTo($tbody);
$.each(headers, function (k, i){
$("<td>").html(row[i]).appendTo($trow);
});
});
Hope that helps.
Upvotes: 0
Reputation: 9388
To answer your question regarding Object.keys
, you would need to filter against a known set.
For example:
let keysToRender = ['index', 'age'];
Object.keys(response[0]).filter(key => { return ~keysToRender.indexOf(key) })
Here's a solution I threw together (it's based on the fiddle link I posted in my comments to you, but cleaned up) which uses map
. Personally, I prefer map
over $.each
(for this problem) as there's slightly less overhead.
Fiddle: http://jsfiddle.net/x3p79jfs/
Edit: Here's a fiddle that maintains order based on response (as you mentioned in the other comment) - http://jsfiddle.net/x3p79jfs/1/
Hope it helps!
$.getJSON('https://next.json-generator.com/api/json/get/E1qcwkNxr', function(res) {
// Extracts values from response
const getModelFromKeys = (res, keys) => {
return res.map(item => {
return keys.map(key => {
return item[key];
});
});
};
// Build template to append
const buildTableFromModel = (header, body) => {
let reducer = (arr, func, acc) => {
return arr.reduce(func, acc);
};
let getTemplateCell = (template, item) => template + `<td>${item}</td>`;
let getTemplateRow = (template, item) => template + `<tr>${reducer(item, getTemplateCell, ``)}</tr>`;
return `
<table><thead><tr>
${reducer(header, getTemplateCell, ``)}
</tr></thead><tbody>
${reducer(body, getTemplateRow, ``)}
</tbody></table>
`
};
// Our expected set of keys to render (note first, last names which do not exist)
let pii_table = ['age', 'index', 'first_name', 'last_name', 'registered', 'balance', 'eyeColor'];
// Filter expected keys against ajax response
// let filteredKeys = Object.keys(res[0]).filter(key => {
// return ~pii_table.indexOf(key);
// });
// Filter expected keys against ajax response
let responseKeys = Object.keys(res[0]);
let filteredKeys = pii_table.filter(key => {
return ~responseKeys.indexOf(key);
});
// Build Table Model From Filtered Keys
let firstTableModel = getModelFromKeys(res, filteredKeys);
// Append table to Body
document.body.innerHTML += buildTableFromModel(filteredKeys, firstTableModel);
});
td {
padding: 3px;
text-align: center;
}
thead {
color: white;
background-color: #777;
}
tr:nth-child(2n) {
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Upvotes: 1