Updating HTML data from JS file (HTML/JQuery)

Issue

I am making a coronavirus tracking website, and I’m having trouble getting the data to update automatically in the HTML file. Here is my JS code:

(async()=>{
    // define some globals
  var update = async()=>{

    // download the data
    console.log('Report: Download Started');
    var url = 'https://cov19.cc/report.json?v='+Math.random();
    var res = await fetch(url);
    var report = await res.json();
    
    // set the last updated time
    $('#last_updated').text(moment.utc(report.last_updated).fromNow());

    // get variable data
    var world = report.regions.world;

    var total_confirmed = report.regions.world.totals.confirmed;
    document.getElementById("total_confirmed").innerHTML = total_confirmed.commaSplit();

    var total_critical = world.totals.critical;
    document.getElementById("total_critical").innerHTML = total_critical.commaSplit();

    var total_deaths = world.totals.deaths;
    document.getElementById("total_deaths").innerHTML = total_deaths.commaSplit();

    var total_active = world.totals.confirmed - (world.totals.deaths + world.totals.recovered);
    document.getElementById("total_active").innerHTML = total_active.commaSplit();

    var total_recovered = world.totals.recovered;
    document.getElementById("total_recovered").innerHTML = total_recovered.commaSplit();

    // hide the loading icon
    $('#loader').hide();
    };

    // store last updated date
    var old_last_updated;

    // check for the last update
    var update_check = async()=>{
    console.log('Checking for updates');
    var res = await fetch('https://cov19.cc/last_updated.txt');
    var last_updated = await res.text();
        
    // if the last updated date is newer than the stored last updated date then update the variable and update the table with the new data
    if(old_last_updated == last_updated)return;
    old_last_updated = last_updated;

    update();
    };

    // initialize
    update_check();

    // check for updates every 60 seconds
    setInterval(update_check, 60000);
})();

    //cov19 prototypes
    String.prototype.commaSplit = function() {
    return this.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    };
    Number.prototype.commaSplit = String.prototype.commaSplit;

This is how I am showing the data in the HTML file:

<p style="font-size: 60px; color: #F5F2D0; 
                            text-align: center; font-weight: 600; margin-bottom: 0";
                            id="total_confirmed">
                        </p>

The data only changes when I refresh the page, how can I make it so that it updates automatically without having to refresh the page? I thought since the variables are in the update function they would change automatically. Do I have to call the function in my HTML code?
I have been stuck on this for a long time and would really appreciate the help. I am still new to JQuery so this may be an easy fix. Thanks

Solution

I think that your code works quite OK. You don’t see any update, because of

if(old_last_updated == last_updated)return;
old_last_updated = last_updated;

This is a sensible check to decide if you want to update the DOM or not (if the data hasn’t changed, then why should you?)

I just added a timestamp before this check to show, that the DOM updates (without a problem), so it’s your check that doesn’t let it update. (I also changed the frequency of update checks so testing is easier: to 10s from 60s.)

(async() => {
  // define some globals
  var update = async() => {
    // download the data
    console.log('Report: Download Started');
    var url = 'https://cov19.cc/report.json?v=' + Math.random();
    var res = await fetch(url);
    var report = await res.json();

    // set the last updated time
    jQuery('#last_updated').text(moment.utc(report.last_updated).fromNow());

    // get variable data
    var world = report.regions.world;

    var total_confirmed = report.regions.world.totals.confirmed;
    document.getElementById("total_confirmed").innerHTML = total_confirmed.commaSplit();

    var total_critical = world.totals.critical;
    document.getElementById("total_critical").innerHTML = total_critical.commaSplit();

    var total_deaths = world.totals.deaths;
    document.getElementById("total_deaths").innerHTML = total_deaths.commaSplit();

    var total_active = world.totals.confirmed - (world.totals.deaths + world.totals.recovered);
    document.getElementById("total_active").innerHTML = total_active.commaSplit();

    var total_recovered = world.totals.recovered;
    document.getElementById("total_recovered").innerHTML = total_recovered.commaSplit();

    // hide the loading icon
    $('#loader').hide();
  };

  // store last updated date
  var old_last_updated;

  // check for the last update
  var update_check = async() => {
    console.log('Checking for updates');
    var res = await fetch('https://cov19.cc/last_updated.txt');
    var last_updated = await res.text();
    console.log('last_updated.txt:', last_updated)

    // just to see that your code updates:
    $('#query_time').text(Date.now());

    // if the last updated date is newer than the stored last updated date then update the variable and update the table with the new data
    if (old_last_updated == last_updated) return;
    old_last_updated = last_updated;



    update();
  };

  // initialize
  update_check();

  // check for updates every 60 seconds
  setInterval(update_check, 10000);
})();

//cov19 prototypes
String.prototype.commaSplit = function() {
  return this.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
Number.prototype.commaSplit = String.prototype.commaSplit;
.display-class {
  /*font-size: 60px;
  color: #F5F2D0; 
  text-align: center;
  font-weight: 600;
  margin-bottom: 0;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<p id="total_confirmed" class="display-class">TOTAL CONFIRMED</p>
<div id="last_updated"></div>
<div id="query_time"></div>

ADDED

Here’s a little modified version of your code:

(async() => {
  // define some globals
  var update = async(text, updateTime) => {
    // download the data
    console.log('Report: Download Started');
    var url = 'https://cov19.cc/report.json?v=' + Math.random();
    var res = await fetch(url);
    var report = await res.json();

    // set the last updated time
    jQuery('#last_updated').text(moment.utc(report.last_updated).fromNow() + ` queried: ${updateTime}`);

    // get variable data
    var world = report.regions.world;

    var total_confirmed = report.regions.world.totals.confirmed;
    document.getElementById("total_confirmed").innerHTML = total_confirmed.commaSplit() + ` queried: ${updateTime}`;

    var total_critical = world.totals.critical;
    document.getElementById("total_critical").innerHTML = total_critical.commaSplit() + ` queried: ${updateTime}`;

    var total_deaths = world.totals.deaths;
    document.getElementById("total_deaths").innerHTML = total_deaths.commaSplit() + ` queried: ${updateTime}`;

    var total_active = world.totals.confirmed - (world.totals.deaths + world.totals.recovered);
    document.getElementById("total_active").innerHTML = total_active.commaSplit() + ` queried: ${updateTime}`;

    var total_recovered = world.totals.recovered;
    document.getElementById("total_recovered").innerHTML = total_recovered.commaSplit() + ` queried: ${updateTime}`;

    // hide the loading icon
    $('#loader').hide();
  };

  // store last updated date
  var old_last_updated;

  // check for the last update
  var update_check = async() => {
    console.log('Checking for updates');
    var res = await fetch('https://cov19.cc/last_updated.txt');
    var last_updated = await res.text();
    console.log('last_updated.txt:', last_updated)

    // if the last updated date is newer than the stored last updated date then update the variable and update the table with the new data
    // if (old_last_updated == last_updated) return;
    old_last_updated = last_updated;

    update(last_updated, Date.now());
  };

  // initialize
  update_check();

  // check for updates every 60 seconds
  setInterval(update_check, 10000);
})();

//cov19 prototypes
String.prototype.commaSplit = function() {
  return this.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
Number.prototype.commaSplit = String.prototype.commaSplit;
.display-class {
  /*font-size: 60px;
  color: #F5F2D0; 
  text-align: center;
  font-weight: 600;
  margin-bottom: 0;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<p id="total_confirmed" class="display-class">TOTAL CONFIRMED</p>
<div id="last_updated"></div>
<div id="total_confirmed"></div>
<div id="total_critical"></div>
<div id="total_deaths"></div>
<div id="total_active"></div>
<div id="total_recovered"></div>

Here I removed the sensible update check and added the query time to the end of all strings displayed – you can see that they update nicely (interval of 10s). No problem with that.

SOMETHING SMALL

(async() => {
  // define some globals
  var update = async(text, updateTime) => {
    // download the data
    console.log('Report: Download Started');
    var url = 'https://cov19.cc/report.json?v=' + Math.random();
    try {
      var res = await fetch(url);
      var report = await res.json();
    } catch (err) {
      console.log(err)
    }

    // set the last updated time
    document.getElementById('last_updated').innerHTML = moment.utc(report.last_updated).fromNow() + `<br />query time: ${new Date(Date.now())}<br /><br />`

    // adding total confirmed
    document.getElementById('total_confirmed').textContent = 'TOTAL CONFIRMED: ' + report.regions.world.totals.confirmed.toLocaleString('en-US')

    // set data list
    document.getElementById('data_container').innerHTML = createHTMLTemplate(report.regions.world.totals)
    // hide the loading icon
    $('#loader').hide();
  };

  // store last updated date
  var old_last_updated;

  // check for the last update
  var update_check = async() => {
    console.log('Checking for updates');
    var res = await fetch('https://cov19.cc/last_updated.txt');
    var last_updated = await res.text();

    // if the last updated date is newer than the stored last updated date then update the variable and update the table with the new data
    // if (old_last_updated == last_updated) return;
    old_last_updated = last_updated;

    update(last_updated, Date.now());
  };

  // initialize
  update_check();

  // check for updates every 10 seconds
  setInterval(update_check, 10000);
})();

function createHTMLTemplate(data) {
  let html = ''
  for (let key in data) {
    html += `<div>${key}: ${data[key].toLocaleString('en-US')}</div>`
  }
  html += `<div>active: ${(data.confirmed - (data.deaths + data.recovered)).toLocaleString('en-US')}</div>`
  return html
}
.display-class {
  /*font-size: 60px;
  color: #F5F2D0; 
  text-align: center;
  font-weight: 600;
  margin-bottom: 0;*/
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.26.0/moment.min.js"></script>
<p id="total_confirmed" class="display-class">TOTAL CONFIRMED</p>
<div id="last_updated"></div>
<div id="data_container"></div>

You can make the code more maintainable by
– extracting code to functions (like creating the HTML template)
– remove unnecessary functions (commaSpit() is such a function – toLocaleString('en-US') does the same (and more)

Answered By – muka.gergely

Answer Checked By – Willingham (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.