# CSV Filled Table (Via JS) Not Loading In Browser Until Manual Refresh

**URL:** <https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710>\
**Category:** Help\
**Created:** [November 19, 2021, 9:36am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710 "2021-11-19T09:36:45Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![clintjb](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/clintjb/32/4105_2.png) [@clintjb](https://talk.jekyllrb.com/u/clintjb)\
**Post date:** [November 19, 2021, 9:36am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/1 "2021-11-19T09:36:45Z")

</div>

Hi All,  
I basically want to render a CSV as a table on my Jekyll site - I have this working with the below script.

Only problem is it never seems to load the table first time, I need to click refresh in the browser for it to appear - the code seems to work fine standalone so am thinking it may have something to do with how its embedded with Jekyll? Does anyone have any ideas as to what could be the cause of this?

You can see the behavior on the page here around 2/3s down - [A350 Flights With GH Actions – Clint Bird](https://clintbird.com/blog/ghactions-a350-flights-post)

Thanks for any hints!

```auto
<script>
    fetch('https://raw.githubusercontent.com/clintjb/A350-Tracking/main/flight_data_a350.csv'
    ).then((response) => {
        return response.text();
    }).then((text) => {
        document.getElementById('A350').innerHTML = tbl(text);
    })

    function tbl(csv) {
        return csv.split('\n')
            .map(function (tr, i) {
                return '<tr><td>' +
                    tr.replace(/,/g, '</td><td>') +
                    '</td></tr>';
            })
            .join('\n');
    }

</script>

<table border="0" style='font-size:50%' id="A350"></table>

```

---

<div class="post-metadata">

**Author:** ![ashmaroli](https://avatars.discourse-cdn.com/v4/letter/a/df705f/32.png) [@ashmaroli](https://talk.jekyllrb.com/u/ashmaroli)\
**Post date:** [November 19, 2021, 9:51am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/2 "2021-11-19T09:51:42Z")

</div>

> [@clintjb](#):
>
> Only problem is it never seems to load the table first time, I need to click refresh in the browser for it to appear - the code seems to work fine standalone so am thinking it may have something to do with how its embedded with Jekyll?

The reason could be because the table is dynamically rendered as a result of resolving a JS Fetch promise.  
There’s a possibility that there’s some delay in having the promise resolved. But rest of the page continues to be rendered without waiting for the table being rendered first.

This has nothing to do with Jekyll and is purely in the domain of JS.

* * *

Edit:

@clintjb You could add some `console.log` statements to your JS depending on whether the _promise_ status is _pending_, or _fulfilled_.

```javascript
<script>
  console.log('Fetching CSV data..');
  fetch('https://raw.githubusercontent.com/clintjb/A350-Tracking/main/flight_data_a350.csv'
  ).then((response) => {
      console.log('Fetch Successful.');
      return response.text();
  }).then((text) => {
      console.log('Rendering table..');
      document.getElementById('A350').innerHTML = tbl(text);
      console.log('Table rendered successfully.');
  })

  function tbl(csv) {
      return csv.split('\n')
          .map((tr, i) => '<tr><td>' + tr.replace(/,/g, '</td><td>') + '</td></tr>')
          .join('\n');
  }
</script>

```

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 20, 2021, 5:24pm UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/3 "2021-11-20T17:24:07Z")

</div>

@clintjb is the issue on Jekyll as a local dev server? Because maybe something is going with livereloading or other assets on the page which are affecting it.

It should not be an issue on a deploy site or plain HTML, as Jekyll doesn’t have a role after the site is built.

## Loading issues

I’d say check your dev tools when the page loads.

I’m seeing no gets from `document.getElementById` when I load that page.

## Ordering

You can also make sure that your script only loads only _after_ the body is rendered, so that the `document.getElementById('A350')` bit has an actual element to find.

You left out an important bit and that is when element is rendered. I found this on your site

```auto
<script type="8b0732c79ba4c7d352b62ab6-text/javascript">
  console.log('Fetching CSV data..');
  fetch('https://raw.githubusercontent.com/clintjb/A350-Tracking/main/flight_data_a350.csv'
  // ...
</script>
<table border="0" style="font-size:50%" id="A350"></table>

```

You may be getting inconsistent results because _sometimes_ the CSV request is slow and then the body is already loaded, _other times_ the request is after and then the JS has no element to attach to and errors out.

### Solutions

Reorder:

```auto
<table border="0" style="font-size:50%" id="A350"></table>
<script>
  console.log('Fetching CSV data..');
  fetch('https://raw.githubusercontent.com/clintjb/A350-Tracking/main/flight_data_a350.csv'
  // ...
</script>

```

Or put your script tag high up on the page in the `head` and have it run after the body has loaded.

```auto
<head>
<script>
  window.onload = function () {
    console.log('Fetching CSV data..');
    fetch('https://raw.githubusercontent.com/clintjb/A350-Tracking/main/flight_data_a350.csv'
    // ...
  }
</script>
</head>
<body>
    <table border="0" style="font-size:50%" id="A350"></table>
</body>

```

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 20, 2021, 5:59pm UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/4 "2021-11-20T17:59:26Z")

</div>

# Advice

Some other improvements to suggest

### CDN

Turn your data site in to a static site.

Go to [GitHub - clintjb/A350-Tracking: An experiment to see how the new actions feature works combined with an API pull of flight data on the A350](https://github.com/clintjb/A350-Tracking) , add `.nojekyll` as an empty file in the root (for faster deploys) and enable GitHub Pages

You’ll be able to load the CSV as:

```auto
"https://clintjb.github.io/A350-Tracking/flight_data_a350.csv"

```

I did some tests using my CSV of a few lines.

The timing for the two was close in this case when I used `curl` - of 0.04 seconds or 0.4 seconds without hitting cache.

- `https://michaelcurrin.github.io/network-graphs/assets/data/sample.csv`
- `https://raw.githubusercontent.com/MichaelCurrin/network-graphs/master/assets/data/sample.csv`

I did notice from the headers that the [GitHub.io](http://GitHub.io) one has cache length of 600 seconds and the other was 300 seconds, so in that regard it is better.

## Fetch async-await

If you are tired of dealing with chained `.then` promises, use the async await syntax.

Also note that `fetch` will _not_ throw an error on 4XX or 5XX response, so you should handle that as below, based on the docs.

```auto
function tbl(csv) {
  // ..
}

// You have to wrap your main logic in `async` for it to work.
(async function() {
  const URL = 'https://raw.githubusercontent.com/clintjb/A350-Tracking/main/flight_data_a350.csv'
  const TARGET_ID = 'A350'

  const resp = await fetch(URL);
  if (!resp.ok) {
    throw new Error(`${URL} HTTP error: ${resp.status} - ${resp.statusText}`);
  }
  const text = await resp.text();
  const tableHtml = tbl(text)
 
  const el = document.getElementById(TARGET_ID)
  el.innerHtml = tableHtml
})()

```

_Edit: I needed `()` at the every end so it does something_

See my [fetch guide](https://michaelcurrin.github.io/dev-cheatsheets/cheatsheets/javascript/general/request/fetch.html)

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 20, 2021, 6:32pm UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/5 "2021-11-20T18:32:34Z")

</div>

BTW Looking at the workflow on the data site

You can make one workflow if you prefer, and have it run in two ways.

```auto
on:
  workflow_dispatch:

  schedule:
    - cron: "0 */8 * * *"

jobs:
  # ...

```

---

<div class="post-metadata">

**Author:** ![clintjb](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/clintjb/32/4105_2.png) [@clintjb](https://talk.jekyllrb.com/u/clintjb)\
**Post date:** [November 23, 2021, 9:03pm UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/6 "2021-11-23T21:03:11Z")

</div>

Hi @MichaelCurrin  
Dude! Your reply is nothing short of brilliant - firstly, went through your points and learnt a few new things in there…  
That CDN topic itself was interesting to understand - strangely (it may have something to do with my HTTPS routing via Cloudflare?) but basically after making the swap over, I could directly link to the file e.g.

```auto
"https://clintjb.github.io/A350-Tracking/flight_data_a350.csv"

```

But when I call it in the Jekyll site nothing shows at all 🤷‍♂️ - nevertheless interesting to understand the advantages and potential performance benefits of converting it directly to static.

More importantly though was that your solutions you proposed unfortunately didn’t work in my case. I tried both ordering solutions but unfortunately they didn’t pan out - I wanted this to be a quick and dirty experiment and in the end this damn table rendering issue is taking more time than anything else…  
Sorry bud, with the amount of effort you went to in your feedback I was hoping as much as you this would’ve provided me the solution…

As said though, appreciate the efforts and if its any minor consolation Ive definitely learnt a few things from your insights anyway!

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 24, 2021, 7:53am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/7 "2021-11-24T07:53:23Z")

</div>

I’m that you learnt something. Web development is complex and often you don’t know what is there is out there, so you have some direction to explore more and be better equipped.

Yeah it is frustrating when it doesn’t work. Take a break from it or step back and try a different angle, to save getting stuck and feeling defeated.

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 24, 2021, 7:55am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/8 "2021-11-24T07:55:42Z")

</div>

Also I’d recommend watching a YouTube video on dev tools for Chrome or Firefox.

Being able to understand the JS log and network tab and the DOM helps me for daily work and my projects. It tell you what is or isn’t running and clue as to why (such as the error message in the console section)

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 24, 2021, 8:05am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/9 "2021-11-24T08:05:33Z")

</div>

Something else to add as another approach.

If you are tired of writing JS to fetch data on the frontend, consider a backend solution

If you have the CSV in the same repo as the site like in `_data/my_file.csv`, you can access the data when the site builds as

```auto
{{ site.data.my_csv }}

```

And whenever you change the CSV with a commit, the site will rebuild with latest data.

I have a tutorial I added to Jekyll docs on rendering CSV with Jekyll

> **[Tabulate CSV Data](https://jekyllrb.com/tutorials/csv-to-table/)**
>
> This tutorial shows how to use Jekyll to read a CSV and render the data as an HTML table.

* * *

If you want to keep the data in a separate repo, you can easily add a command to run add build time

The simplest is to use a curl command in the shell and have the file ignored by Git. i.e. file is not stored in the site repo GitHub but only stored on the server that is building

e.g.

```auto
bundle install
curl https://... > _data/my_data.csv
bundle exec jekyll serve --trace 

```

That will work locally and on Netlify. Or GH Pages with GH Actions.

You’ll just have to rebuild the site with a manual trigger whenever the CSV data changes. Or build on a schedule like nighty or weekly, for frequently changing data.

* * *

Or you can write a Ruby plugin that fetches the data and handles error codes like 400 properly.

but the one line curl approach is elegant and short and worth doing still

---

<div class="post-metadata">

**Author:** ![ashmaroli](https://avatars.discourse-cdn.com/v4/letter/a/df705f/32.png) [@ashmaroli](https://talk.jekyllrb.com/u/ashmaroli)\
**Post date:** [November 24, 2021, 10:29am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/10 "2021-11-24T10:29:28Z")

</div>

@clintjb Your idea and script works fine if one accesses the webpage directly via the permalink (the link you provided in the opening post). It also works as expected if one were to refresh the webpage (successful render on every refresh).

The only time **it doesn’t work** is if I were to _navigate to the page_ from `https://clintbird.com/blog/`.

I’m hypothesizing that the result should be the same if you were to _navigate_ to the A350 page from say, `/business/` or `/stuff/`, etc.

If the hypothesis is valid, then the _bug_ is in the theme’s global script.

Try building your site with a theme that doesn’t need JavaScript to render a webpage’s content sections.

---

<div class="post-metadata">

**Author:** ![BillRaymond](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/billraymond/32/5963_2.png) [@BillRaymond](https://talk.jekyllrb.com/u/BillRaymond)\
**Post date:** [November 25, 2021, 1:13am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/11 "2021-11-25T01:13:06Z")

</div>

It looks like you are getting some great responses here. I’m not sure if you are aware of this, but Jekyll supports data, so you can render it without JS.

Here is a video that specifically covers using custom data files in Jekyll:

[![](https://canada1.discourse-cdn.com/flex030/uploads/jekyllrb/original/2X/0/0f3638ad095a50c603656af414a13b7715fba1b0.jpeg "Working with Jekyll Data, Part 3: Custom Data") ](https://www.youtube.com/watch?v=kKU-lMv5OZM)

There are more videos there if you are interested, but with this one I specifically cover csv, JSON, and other file types. Jekyll also supports TSV (tab separated variables)

---

<div class="post-metadata">

**Author:** ![MichaelCurrin](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/michaelcurrin/32/2340_2.png) [@MichaelCurrin](https://talk.jekyllrb.com/u/MichaelCurrin)\
**Post date:** [November 25, 2021, 5:57am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/12 "2021-11-25T05:57:36Z")

</div>

I am seeing the table render fine as well.

But as mentioned before - it is fragile because of the timing of loading the page and the element not being ready. I would suggest one improvement as before and this just making sure the script tag for the table is put _after_ the div it is targeting.

`https://github.com/clintjb/clintjb.github.io/blob/master/_includes/a350_csv.html`

And on what Ash is saying - if you disable JavaScript for browser, then whole page is just about blank. Which is not typical for a Jekyll site and means it is not so much a static site anymore (maybe more like SinglePage App such as with React). Which means the table and also the rest of the site is not visible to some users and also not to seach engines (which have limited ability to run JS - they sometimes _can_ but limit total processing time of how much they _do_).

`https://clintbird.com/blog/ghactions-a350-flights-post`

 ![Screen Shot 2021-11-25 at 7.52.13 am](https://canada1.discourse-cdn.com/flex030/uploads/jekyllrb/original/2X/a/a6f89f6caf4b1898275c1a4c5b20dcdcbe148371.png)

---

<div class="post-metadata">

**Author:** ![clintjb](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.jekyllrb.com/clintjb/32/4105_2.png) [@clintjb](https://talk.jekyllrb.com/u/clintjb)\
**Post date:** [November 28, 2021, 7:38am UTC](https://talk.jekyllrb.com/t/csv-filled-table-via-js-not-loading-in-browser-until-manual-refresh/6710/13 "2021-11-28T07:38:21Z")

</div>

> [@MichaelCurrin](#):
>
> Something else to add as another approach.
> 
> If you are tired are writing JS to fetch data on the frontend, consider a backend solution
> 
> If you have the CSV in the same repo as the site like in `_data/my_file.csv` , you can access the data when the site builds as

So this is the option I went for in the end - created another action to push them across to the main site and used your Tabualte tutorial…

Genuinely mean it when I say thanks @MichaelCurrin so much for the solution (as well as the time you spent highlighting an ENORMOUS number of other minor learning’s, fixes, best practices, code contributions etc) Honestly mate you went so far above and beyond - learnt a lot these past days - thanks!
