Avoid writing same function multiple times

Viewed 72

I'm using ajax to load json data into several accordion tables on the same html page. So far, I have the same function written twice to output 2 tables, but I need 16 more tables. Having the same function written out 18 times doesn't seem dry at all, so I'm thinking there must be better way.

let myArray = [];

      $.ajax({
        method: "GET",
        url: "https://chrisjschreiner.github.io/data/verbs1.json",
        success: function (response) {
          myArray = response;
          buildTable1(myArray[0]);
          buildTable2(myArray[1]);
        },
      });

      let buildTable1 = (data) => {
        let table = document.getElementById("myTable1");

        for (const [key, value] of Object.entries(data)) {
          let row = `<tr>
                      <td>${key}</td>
                      <td>${value}</td>
                   </tr>`;
          table.innerHTML += row;
        }
      };
      let buildTable2 = (data) => {
        let table = document.getElementById("myTable2");

        for (const [key, value] of Object.entries(data)) {
          let row = `<tr>
                      <td>${key}</td>
                      <td>${value}</td>
                   </tr>`;
          table.innerHTML += row;
        }
      };

Any suggestions?

1 Answers

In order to avoid rewriting functions, pass in variables:

buildTable(selector, response, ...indices)

Parameters

  • selector: string - selector of the element that'll contain all of the <table>s
  • response: array of objects - the parsed JSON from the server
  • ...indices: '*' or comma delimited list of numbers - the spread operator will gather all of the numbers or '*' into an array
    If '*' is passed, it will be an array of numbers that represent all of the indices within response.
    '*' passed as [0 to data.length-1]
    
    If number(s) are passed, those will represent the index of each object of response. The following example would be for the first, third and seventh object of response
    0, 2, 6 passed as [0, 2, 6]
    

The following example will create a <table> for each applicable object within the array

$.ajax({
  method: "GET",
  url: "https://chrisjschreiner.github.io/data/verbs1.json",
  success: function(response) {
    buildTable1('main', response, '*');
  },
});

const buildTable1 = (selector, response, ...indices) => {
  const node = document.querySelector(selector);
  const data = JSON.parse(JSON.stringify(response));
  const idcs = indices.includes('*') ? data.map((o, i) => i) : indices;
  const table = document.createElement('table');

  data.forEach((obj, idx) => {
    if (idcs.includes(idx)) {
      let tClone = table.cloneNode(true);
      node.appendChild(tClone);
      Object.entries(obj).forEach(([key, val]) => {
        let row = tClone.insertRow();
        row.innerHTML = `<td>${key}</td><td>${val}</td>`;
      });
    }
  });
};
table {
  width: 80%;
  margin: 10px;
  table-layout: fixed;
  border: 1px solid black;
  border-collapse: collapse;
}

td {
  padding: 0 5px;
  border-top: 1px solid red;
  vertical-align: top;
}

tr:first-child td {
  border-top: 0px solid transparent;
}

td:first-child {
  width: 35%;
  border-right: 3px dotted red;
}
<main>
  <!--Tables will be added here -- selector = 'main'-->
</main>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Related