Search code examples
javascripthandlebars.js

Handlebars re-compile templates


I'm working with handlebars and I have this situation.

I do a request to a server, and get all the data I need to put it on the views. I use handlebars to put that data, and have no problem.

Now, I need to do the request every 1 or 2 minutes. But when I'm going to put the data again in the views, there's an error. This is because the template I've already compiled and the tag where the template will be inserted isn't there any more.

Any solutions? I left my code here:

In my view I have this:

<script id="vessels-info" type="text/x-handlebars-template">
        {{#vessel}}
        <div id="content-vessels" class="col-xs-12 col-sm-6">
        <div class="page-header">
        <h2 id="shipnametitle">{{vesselname}}</h2>
        </div>
        <div class="row">
        <div class="col-sm-12">
        <div class="list-group">
        <a class="list-group-item">
        <b>ID</b>: {{id}} 
        </a>
        <a class="list-group-item">
        <b>Posición GPS</b>: ({{lat}} , {{long}})
        </a>
        <a class="list-group-item {{alertafecha gpsdate}}" >
        <b>Fecha GPS</b>: {{gpsdate}} 
        </a>
        <a class="list-group-item {{alertavelocidad speed}}">
        <b>Velocidad</b>: {{speed}}
        </a>
        {{#if rpm}}
        <a class="list-group-item">
        <b>RPM</b>: {{rpm}}
        </a>
        <a class="list-group-item {{alertafecha gpsdate}}" class="{{alerta}}">
        <b>Fecha RPM</b>: {{rpmdate}}
        </a>
        {{/if}}
        </div>
        </div>
        </div>
        </div>
        {{/vessel}}
            </script>

And in my JavaScript, I have this:

function initAlerts() {
    try {
        getVesselsRequest(alertas, "mapa");
        setInterval(initAlerts, 60000);
    } catch (err) {
        console.log(err);
    }
}
function alertas(vessels, mapa) {
    var fuente = $('#vessels-info').html();
    var plantilla = Handlebars.compile(fuente);
    var html = plantilla(vessels);
    $('#map-container').html(html);
}

The error is this:

Uncaught Error: You must pass a string or Handlebars AST to Handlebars.compile. You passed undefined

I know the error is that when I pass $('#vessels-info').html(); to the compile function, the tag <script> with the ID 'vessels-info' is not there any more, cause was already compiled.

Any help?


Solution

  • In this case you can keep a reference to the template as a string. Something like:

        var templateString = $('#vessels-info').html();
    
        function alertas(vessels, mapa) {
            var plantilla = Handlebars.compile(templateString);
            var html = plantilla(vessels);
            $('#map-container').html(html);
        }
    

    Putting a variable like this in the global scope is bad practice. And if your application grows more complicated I would suggest creating an object which would then hold the state and do the periodic updates.