0

This is my markup/HTML where the table will be inserted:

<section class="page page-info">
  <div class="contact">
    <div class="container">
      <div class="row">
        <div class="col-sm-8 col-sm-offset-2">
            <table>
                <!-- Table goes here! -->
            </table>
        </div>
      </div>
    </div>
  </div>
</section>

Some variables in the outer scope so they can be accessed by all functions, followed by the fetch call and the table creating module :

var products;
let table = document.querySelector('table');

window
  .fetch('/pages/products-api')
  .then(resp => resp.json())
  .then(function(data) {
    products = data;
    GenerateTableModule.initialize(table, products);

    console.log('data.results ', data);
  })
  .catch(err => console.dir(err));

const GenerateTableModule = (function() {
  let table = null;
  let data = [];

  function initialize(tableSelector, arr) {
    table = tableSelector;
    data = arr;
  }

  const _generateTableHead = function() {
    let thead = table.createTHead();
    let row = thead.insertRow();
    for (let key in data[0]) {
      let th = document.createElement('th');
      let text = document.createTextNode(key);
      th.appendChild(text);
      row.appendChild(th);
    }
  };

  const generateTable = function() {
    for (let element of data) {
      let row = table.insertRow();
      for (key in element) {
        let cell = row.insertCell();
        let text = document.createTextNode(element[key]);
        cell.appendChild(text);
      }
    }
    _generateTableHead();
  };
  return { initialize, generateTable };
})();

GenerateTableModule.generateTable();

The actual error I get in the console is:

updating-upsell-on-the-view-cart.js?25617:26 Uncaught TypeError: Cannot read property 'createTHead' of null at _generateTableHead (updating-upsell-on-the-view-cart.js?25617:26) at Object.generateTable (updating-upsell-on-the-view-cart.js?25617:45) at updating-upsell-on-the-view-cart.js?25617:50

But how can that be when I have my data being returned in the console.log in my fetch?!

data.results {products: Array(88)}

Thanks in advance!

Antonio Pavicevac-Ortiz
  • 7,239
  • 17
  • 68
  • 141
  • Call `generateTable` only *after* `initialize` has been called, so that the closure-scoped `table` variable is defined at that point – CertainPerformance Oct 04 '19 at 03:46
  • @CertainPerformance Thanks! I tried that before but that yields `updating-upsell-on-the-view-cart.js?25620:36 Uncaught TypeError: data is not iterable at Object.generateTable` – Antonio Pavicevac-Ortiz Oct 04 '19 at 04:17
  • 1
    the problem is that `table = tableSelector;` isn't executed until after `.then(function(data) {` is executed, and this `.then` is executed at *some unknown time in the future* - that's how asynchrony works ... but you call `GenerateTableModule.generateTable();` before the `fetch` has even had a chance to get any response - because it's asynchronous – Bravo Oct 04 '19 at 04:18
  • @Bravo so should i wrap ‘GenerateTableModule’ in a ‘setTimeOut’ or create a function that takes it as a callback? – Antonio Pavicevac-Ortiz Oct 04 '19 at 04:26
  • no, `setTimeout` is hacky and unreliable, callbacks could work but would probably make the code harder to read - using promises (you already have one in fetch anyway) and the new async/await syntax makes it fairly simple - see if [this pastebin](https://pastebin.com/smKQPXE8) helps you to understand what you could do – Bravo Oct 04 '19 at 04:29
  • @Bravo Thanks my friend I like and understand your approach but now I am getting `Uncaught (in promise) TypeError: data is not iterable at Object.generateTable`! I am confused! :) – Antonio Pavicevac-Ortiz Oct 04 '19 at 14:46
  • @Bravo I overlooked that the array I was looking for was on a property of `data` i.e. `Array.isArray(data.products) === true`, thanks my friend! – Antonio Pavicevac-Ortiz Oct 04 '19 at 15:50

0 Answers0