Creating an HTML Table from Any JSON

When working with JSON data in JavaScript, creating an HTML table dynamically can be challenging, especially when dealing with nested JSON. This article walks you through a solution that converts any JSON array into an HTML table. For nested objects, the inner JSON is rendered as a string.

The Code

Here’s the JavaScript code with detailed comments explaining each step:

// Function to recursively create a table for any JSON (object or array)
function createTableFromJson(json) {
  const table = document.createElement('table');
  const tbody = document.createElement('tbody');

  if (Array.isArray(json)) {
    // Handle array: create rows for each element
    const headers = [...new Set(json.flatMap(item => (typeof item === 'object' && item !== null ? Object.keys(item) : [])))];

    // Create table header if array contains objects
    if (headers.length > 0) {
      const thead = document.createElement('thead');
      const headerRow = document.createElement('tr');
      headers.forEach(header => {
        const th = document.createElement('th');
        th.textContent = header;
        headerRow.appendChild(th);
      });
      thead.appendChild(headerRow);
      table.appendChild(thead);
    }

    // Create rows for each array element
    json.forEach(rowData => {
      const tr = document.createElement('tr');
      if (typeof rowData === 'object' && rowData !== null) {
        // If the array contains objects, create cells for each key
        headers.forEach(header => {
          const td = document.createElement('td');
          const cellValue = rowData[header];
          td.appendChild(
            typeof cellValue === 'object' && cellValue !== null
              ? createTableFromJson(cellValue) // Recursively create table for nested objects
              : document.createTextNode(cellValue !== undefined ? cellValue : '')
          );
          tr.appendChild(td);
        });
      } else {
        // If the array contains primitives, show them as a single column
        const td = document.createElement('td');
        td.textContent = rowData;
        td.colSpan = headers.length || 1; // Ensure it spans full width
        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    });
  } else if (typeof json === 'object' && json !== null) {
    // Handle object: treat keys as rows
    Object.entries(json).forEach(([key, value]) => {
      const tr = document.createElement('tr');
      const keyCell = document.createElement('th');
      keyCell.textContent = key;

      const valueCell = document.createElement('td');
      valueCell.appendChild(
        typeof value === 'object' && value !== null
          ? createTableFromJson(value) // Recursively create table for nested objects or arrays
          : document.createTextNode(value !== undefined ? value : '')
      );

      tr.appendChild(keyCell);
      tr.appendChild(valueCell);
      tbody.appendChild(tr);
    });
  } else {
    // Handle primitive values directly
    tbody.innerHTML = `<tr><td>${json}</td></tr>`;
  }

  table.appendChild(tbody);
  return table;
}

CodePen

You can experiment on this Codepen:

See the Pen Creating an HTML Table from Any JSON by Denis Doroshchuk (@webtipshub) on CodePen.