nocrack
nocrack

Reputation: 81

handlebars and JSON data coming from a fetch

I have the code below and have 2 separate issues, so please bear with me on this:

Issue 1 [fetch ?]: The data displayed doesn't change when the JSON change. Sounds like it's a cache issue as I can't see any HTTP request beside the original one. How can I force the JSON file to be downloaded again each time?

Issue 2 [handlebars ?]: with $(document.body).append(html); in the loop, it keeps re-writing the instead of editing the values. How can I change this?

Here is the code:

javascript.js:

async function fetch_json() {
    try {
        var resp = await fetch('http://localhost:8000/data.json', {mode: 'cors'});
        var jsonObj = await jsonify(resp);
        return jsonObj;
    } catch (error) {
        // all errors will be captured here for anything in the try block
        console.log('Request failed', error);
    }
}

html page:

<script id="handlebars-demo" type="text/x-handlebars-template">
    <div>
        {{#each this}}
            Name : {{name}} Value : {{value}} <br>
        {{/each}}
    </div>
</script>
<script type="text/javascript">
    var test_data = [{ "name" : "john doe", "value" : "developer" },{ "name" : "bob boby", "value" : "developer2" }];
    setInterval(function() {
        test_data = fetch_json()
            .then(function(result) {
            html = templateScript(result);
            //$(document.body).append(html);
        })
    }, 1000);

    var template = document.getElementById('handlebars-demo').innerHTML;
    Compile the template data into a function
    var templateScript = Handlebars.compile(template);
    var html = templateScript(test_data);
    $(document.body).append(html);
</script>

any help would be the most appreciated, thank you!

Upvotes: 0

Views: 1480

Answers (1)

user120242
user120242

Reputation: 15268

You should create a DOM element to hold the HTML you are generating. I've created <div id="content"></div> in the example.
You can use $().html() to overwrite the HTML each time instead of appending.
$('#content') selects the DOM element with id=content and then overwrite the HTML inside .html(string) with string.

A common approch to cache busting is to attach a timestamp to the url as a url query param, which I have done by concatenating nocache='+new Date().getTime().
In normal use in production a unique identifier is usually generated per version for each resource after building.

// for demo purposes, overwrite value property with username property
jsonify = x => x.json().then(x => x.map(x => ({ ...x,
  value: x.username
})));

async function fetch_json() {
  try {
    // append timestamp to prevent caching
    var resp = await fetch('https://jsonplaceholder.typicode.com/users?nocache=' + new Date().getTime(), {
      mode: 'cors'
    });
    var jsonObj = await jsonify(resp);
    return jsonObj;
  } catch (error) {
    // all errors will be captured here for anything in the try block
    console.log('Request failed', error);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.6/handlebars.js" integrity="sha256-ZafrO8ZXERYO794Tx1hPaAcdcXNZUNmXufXOSe0Hxj8=" crossorigin="anonymous"></script>

<div id="content"></div>

<script id="handlebars-demo" type="text/x-handlebars-template">
  <div>
    {{#each this}} Name : {{name}} Value : {{value}} <br> {{/each}}
  </div>
</script>
<script type="text/javascript">
  var test_data = [{
    "name": "john doe",
    "value": "developer"
  }, {
    "name": "bob boby",
    "value": "developer2"
  }];
  setInterval(function() {
    test_data = fetch_json()
      .then(function(result) {
        html = templateScript(result);
        $('#content').html(html);
      })
  }, 2000);

  var template = document.getElementById('handlebars-demo').innerHTML;
  //Compile the template data into a function
  var templateScript = Handlebars.compile(template);
  var html = templateScript(test_data);
  $('#content').html(html);
</script>

Upvotes: 1

Related Questions