1
\$\begingroup\$

I'm displaying JSON data in a tabular format on a html page using jQuery.

In the function I'm looping the resp.DATA once to get the key names so it can be displayed as the headings in the table, and a second time to get the values of the keys for all customers.

Can this be done in a way that I only have to loop the resp.DATA once?

JSON data:

 var resp= { "ERROR": [], "DATA": [{ "CustomerID": "234", "BranchID": "1", "LocationID": "26", "FirstName": "Lakshmi " }, { "CustomerID": "235", "BranchID": "1", "LocationID": "6", "FirstName": "Arora " }, { "CustomerID": "236", "BranchID": "1", "LocationID": "68", "FirstName": "S.K.Raman " }, { "CustomerID": "237", "BranchID": "1", "LocationID": "38", "FirstName": "Vidya Rao " }, { "CustomerID": "238", "BranchID": "1", "LocationID": "18", "FirstName": "Raju " }, { "CustomerID": "239", "BranchID": "1", "LocationID": "49", "FirstName": "K.B.Hebbar " }], "META": { "currentPageNumber": "1", "totalPages": "11", "rowcountCurrentPage": "10", "rowcountTotal": "107" } } 

Code:

 var content = '<table class="table table-hover">'; var heading = "<tr>"; var data = ""; $.each(resp.DATA[0], function(ke, va) { heading += '<th>' + ke + '</th>'; }); $.each(resp.DATA, function(key, value) { data += "<tr>"; $.each(value, function(k, v) { data += '<td>' + v + '</td>'; }); data += "</tr>"; }); heading += "</tr>"; content += heading + data + "</table>"; $('#data').append(content); 

HTML file:

<!DOCTYPE html> <html> <head> <title>COnsuming rest webservice</title> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> </head> <body> <h1>Consuming REST api</h1> <div class="container"> <div id="data"> </div> </div> <!-- <input type="button" id="driver" value="Load Data" /> --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> </script> </body> </html> 

You can see a working example here.

\$\endgroup\$

    2 Answers 2

    2
    \$\begingroup\$

    You may take advantage of reduce() and map() functions to have no loop at all, like this:

    $('#data').append( resp.DATA.reduce((table, obj, index) => ( table + ( !index ? ( Object.keys(obj).reduce((header, key) => `${header}<th>${key}`, '<tr>') ) : '' ) + $.map(obj, v => v).reduce((row, value) => `${row}<td>${value}`, '<tr>') ), '<table class="table table-hover">') + '</table>' ); 

    I also used some tagged strings, so more reducing the size of the code.
    Additionally it works a bit faster than the original version, as you can observe with the following snippet.

    var resp= { "ERROR": [], "DATA": [{ "CustomerID": "234", "BranchID": "1", "LocationID": "26", "FirstName": "Lakshmi " }, { "CustomerID": "235", "BranchID": "1", "LocationID": "6", "FirstName": "Arora " }, { "CustomerID": "236", "BranchID": "1", "LocationID": "68", "FirstName": "S.K.Raman " }, { "CustomerID": "237", "BranchID": "1", "LocationID": "38", "FirstName": "Vidya Rao " }, { "CustomerID": "238", "BranchID": "1", "LocationID": "18", "FirstName": "Raju " }, { "CustomerID": "239", "BranchID": "1", "LocationID": "49", "FirstName": "K.B.Hebbar " }], "META": { "currentPageNumber": "1", "totalPages": "11", "rowcountCurrentPage": "10", "rowcountTotal": "107" } } var begTime = performance.now();var content = '<table class="table table-hover">'; var heading = "<tr>"; var data = ""; $.each(resp.DATA[0], function(ke, va) { heading += '<th>' + ke + '</th>'; }); $.each(resp.DATA, function(key, value) { data += "<tr>"; $.each(value, function(k, v) { data += '<td>' + v + '</td>'; }); data += "</tr>"; }); heading += "</tr>"; content += heading + data + "</table>"; $('#data').append(content); $('#data').append(`<h3>OLD: ${performance.now() - begTime} ms</h3>`); var begTime = performance.now(); $('#data').append( resp.DATA.reduce((table, obj, index) => ( table + ( !index ? ( Object.keys(obj).reduce((header, key) => `${header}<th>${key}`, '<tr>') ) : '' ) + $.map(obj, v => v).reduce((row, value) => `${row}<td>${value}`, '<tr>') ), '<table class="table table-hover">') + '</table>' ); $('#data').append(`<h3>NEW: ${performance.now() - begTime} ms</h3>`);
    <!DOCTYPE html> <html> <head> <title>COnsuming rest webservice</title> <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"> </head> <body> <h1>Consuming REST api</h1> <div class="container"> <div id="data"> </div> </div> <!-- <input type="button" id="driver" value="Load Data" /> --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script> </script> </body> </html>

    NOTE: in your version as well as mine, we never take care of the keys in nested objects: they work only if they appear always in the same order!

    \$\endgroup\$
      0
      \$\begingroup\$

      try this one.i didn't test but hope it will work. You can replace search method to contains or indexof whatever..

      var heading = "<tr>"; $.each(resp.DATA, function(key, value) { data += "<tr>"; $.each(value, function(k, v) { if(heading.search( k ) == -1)//allow key not found in existing value heading += '<th>' + k + '</th>'; data += '<td>' + v + '</td>'; }); data += "</tr>"; }); 

      Finally append your strings

      heading += "</tr>"; content += heading + data + "</table>"; $('#data').append(content); 2) var headingArr=[]; $.each(resp.DATA, function(key, value) { data += "<tr>"; $.each(value, function(k, v) { heading.push('<th>' + k + '</th>'); data += '<td>' + v + '</td>'; }); data += "</tr>"; }); remove duplicates using unique from headingArr array and convert array to string.after append it to ur html element. 
      \$\endgroup\$
      2
      • \$\begingroup\$code is working fine but in this code also the ` if(heading.search( k ) == -1)` will be executed many times i,e even when we get all the headings it will check No. of headings* No of k . This will be time consuming as the data iam applying this code is huge.. Thanks for ur response any help will be thankful.\$\endgroup\$
        – Sandeep
        CommentedFeb 3, 2016 at 11:01
      • \$\begingroup\$@Sandeep plz check my another answer.\$\endgroup\$
        – Dharma
        CommentedFeb 3, 2016 at 11:20

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.