Search code examples
javascripthandlebars.jsleaflet

Can I load page level JS after template JS with handlebars?


I am using handlebars and leaflet together. My libs (leaflet) are loaded in the template along with a minified js file below my main content.

Main Template

  <main class="app-content">
    {{{body}}}
  </main>
  {{> footer }}
  <!-- jQuery first, then Bootstrap JS. -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
  <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.1/semantic.min.js"></script>
  <script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
  <script src='/js/main.min.js'></script>

I believe this is best practice. I have pages where there is mapping data passed through to be rendered in leaflet. How do i get this data to flow nicely as at the moment the page level JS is loading before the leaflet libs and, of course, this will not work.

Single View

<script>
$(function() {
  var map = L.map('map').setView([{{data.lat}}, {{data.lng}}], 9);
  var os = new L.BingLayer("XXXXXXXX", { type: 'OrdnanceSurvey' });
  os.addTo(map)
});
</script>

Any pointers would be welcomed.


Solution

  • Are you sure this does not work because of Leaflet being placed after your script?

    Since you wrap your code in jQuery's document ready shorthand function $(function () {}), it should execute only after your page's DOM is ready, including all synchronous scripts loaded and executed. Therefore, your code would execute after Leaflet script has been loaded and executed, even though its tag is placed at the bottom of the page body.

    However there is another issue in your architecture… it is jQuery itself being loaded after your code. Therefore when your code is parsed, jQuery's $ object is not assigned yet!

    A simple workaround would be to load at least jQuery before your page script.

    Demo: http://plnkr.co/edit/LujU9IfGJ9AvJGjr5jIK?p=preview

    Another solution would be to separate your page script from the content, and to display it into a specific placeholder, after jQuery script at least.