2

I have a JSON array like the following:

[
{
    "_id": "5c3296f4c7728833bf7cf334",
    "title": "Update styling",
    "content": "Don't forget to update the styling on the website",
    "category": "Cat2",
    "createdAt": "2019-01-07T00:01:56.375Z",
    "updatedAt": "2019-01-07T00:01:56.375Z",
    "__v": 0
}
]

I want to populate a html table with the Title, Content and Category fields. Currently, I am using the following code to populate the table, but it puts every field in the table, not the ones I want.

const data = [{ "_id": "5c3296f4c7728833bf7cf334", "title": "Update styling", "content": "Don't forget to update the styling on the website", "category": "Cat2", "createdAt": "2019-01-07T00:01:56.375Z", "updatedAt": "2019-01-07T00:01:56.375Z", "__v": 0 }]
const axios = { get: (s) => Promise.resolve({ data }) };

window.addEventListener('load', function() {
  axios.get('http://localhost:2672/categories').then(function (myCategories) {
      // EXTRACT VALUE FOR HTML HEADER. 
      var col = [];
      for (var i = 0; i < myCategories.data.length; i++) {
          for (var key in myCategories.data[i]) {
              if (col.indexOf(key) === -1) {
                  col.push(key);
              }
          }
      }

      // CREATE DYNAMIC TABLE.
      var table = document.createElement("table");

      // CREATE HTML TABLE HEADER ROW USING THE EXTRACTED HEADERS ABOVE.

      var tr = table.insertRow(-1); // TABLE ROW.

      for (var i = 0; i < col.length; i++) {
          var th = document.createElement("th"); // TABLE HEADER.
          th.innerHTML = col[i];
          tr.appendChild(th);
      }

      // ADD JSON DATA TO THE TABLE AS ROWS.
      for (var i = 0; i < myCategories.data.length; i++) {

          tr = table.insertRow(-1);

          for (var j = 0; j < col.length; j++) {
              var tabCell = tr.insertCell(-1);
              tabCell.innerHTML = myCategories.data[i][col[j]];
          }
      }

      // FINALLY ADD THE NEWLY CREATED TABLE WITH JSON DATA TO A CONTAINER.
      var divContainer = document.getElementById("showCategories");
      divContainer.innerHTML = "";
      divContainer.appendChild(table);
  });
});
<div id="showCategories"></div>

Any ideas how I would accomplish this?

3 Answers 3

2

You need to filter your array to only contain the columns you wish to insert into the table. You could filter afterwards with something like:

col = col.filter((data) => {
    return data === 'title' || data === 'content' || data == 'category';
});

or you could filter within your for-loop with a simple if-statement like so:

var col = [];
for (var i = 0; i < myCategories.data.length; i++) {
    for (var key in myCategories.data[i]) {
        if (col.indexOf(key) === -1 && (key === 'title' || key === 'content' || key == 'category')) {
            col.push(key);
        }
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Awesome Ben, that worked perfectly! Is there any way that I can change the name of the headers on the table to make them look prettier, instead of the lowercase title, content and category?
1

Use Array#map and destructuring .

const data = [{"_id":"5c3296f4c7728833bf7cf334","title":"Update styling","content":"Don't forget to update the styling on the website","category":"Cat2","createdAt":"2019-01-07T00:01:56.375Z","updatedAt":"2019-01-07T00:01:56.375Z","__v":0}]

const res = data.map(({title, content, category})=>{
   return `<tr>
      <td>${title}</td>
      <td>${content}</td>
      <td>${category}</td>
   </tr>`;
}).join("");

const table = document.createElement("table");
table.innerHTML = "<tr><th>title</th><th>content</th><th>category</th></tr>";
table.innerHTML += res;
document.body.appendChild(table);
table,tr,th,td {
  border: 1px solid black;
  border-collapse: collapse;
}

th {
  color: white;
  background-color: grey;
}

td,th {
  padding: 10px 5px;
}

Comments

1

const axios = { get: (s) => Promise.resolve({ data: [{ "_id": "5c3296f4c7728833bf7cf334", "title": "Update styling", "content": "Don't forget to update the styling on the website", "category": "Cat2", "createdAt": "2019-01-07T00:01:56.375Z", "updatedAt": "2019-01-07T00:01:56.375Z", "__v": 0 }] }) };

function getSelectColumns() {
  const selected = document.querySelectorAll('#headers option:checked');
  return Array.from(selected).reduce((all, el) => {
    return { ...all, [el.value]: el.text }
  }, {});
}

// ------------------------------------------

function createTable(data, columns = {
  title: 'Title', content: 'Content', category: 'Category'
}) {
  const headerCells = Object.values(columns).map(val => `<th>${val}</th>`);
  const headerRow = `<tr>${headerCells.join('')}</tr>`;
  const dataRows = data.map(obj => {
    return Object.keys(columns).map(key => {
      return `<td>${obj[key] || '-'}</td>`;
    }).join('');
  });
  
  return `<table>${headerRow + dataRows.join('')}</table>`;
}

   function loadDataAndTable() {
  return axios.get('http://localhost:2672/categories').then(res => {
    const div = document.getElementById("showCategories");
    div.innerHTML = createTable(res.data, getSelectColumns());
  });
}

window.addEventListener('load', () => loadDataAndTable());
table {
  text-align: left;
}

th, td {
  padding: 5px 10px;
}

th {
  background: grey;
  color: white;
}
<div id="showCategories"></div>
<hr>
<p>Hold shift and select the columns you want in the table.</p>
<select id="headers" multiple onchange="loadDataAndTable()">
  <option value="title" checked>Title</option>
  <option value="content" checked>Content</option>
  <option value="category" checked>Category</option>
</select>

2 Comments

Thanks Callam, my only problem is that I am using webpack, and I keep getting ReferenceError: regeneratorRuntime is not defined. Any ideas why?
@Frink I think it was the async/await syntax, try thenning the promise instead

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.