Question

i got a page named map.html, its a simple html that uses google maps api:

<head>
    <script type="text/javascript"
            src="https://maps.googleapis.com/maps/api/js?key=XXXXXXX&sensor=true&region=IL">
    </script>
    <script src="map.js" type="text/javascript"></script>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
</head>
        <body>

        </body>
<template name="map">
    <div id="map-canvas"></div>
</template>

and im using iron-router, to route to this page:

this.route("map");

also using pathFor:

<a href="{{pathFor 'map'}}" class="map"><div class="inner">set location</div></a></div>

and finally my google maps initialize function that is in a sperate file named map.js:

$(document).ready(function () {

    function initialize() {
        var TLV = new google.maps.LatLng(32.06461, 34.777222);
        var mapOptions = {
            zoom: 12,
            center: TLV,
            panControl: false,
            zoomControl: false,
            mapTypeControl: true,
            scaleControl: false,
            streetViewControl: false,
            overviewMapControl: true,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        }
        map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);

        marker = new google.maps.Marker({
            position: TLV,
            map: map,
            title: 'Hello World!',
            draggable: true
        });

        google.maps.event.addListener(marker, 'dragend', function (evt) {
            var pos = [marker.getPosition().lat(), marker.getPosition().lng()];
            console.log(pos);
        });
    }
    google.maps.event.addDomListener(window, 'load', initialize);
});

everything works fine if you manually route to http:localhost/map but if you go from localhost and clicks on the link that route to map its not working, now i get it that meteor serves all the files on startup,the qusetion is how to prevent it? or how to serve a certain file to a specific page?

Was it helpful?

Solution

You're not thinking the Meteor way : Meteor bundles ALL your HTML and JS resources to the client(thus the initial slow starting time of a Meteor app on first load, this will probably be addressed later). It means that everything you put in head and body tags will be eventually merged, there is no "page" concept with separate head and body. You shouldn't include third party code the traditional way either, remove all of your resources from the head tag. You should put your own code (map.js) in "client/js/" and your libs in "client/compatibility/", they will get bundled and sent to the client.

Now what's happening is that your map.js code is executed the traditional jQuery way on document.ready, which happens ONLY ONE TIME in a Meteor app because we're talking about a Single Web Page app. However when you navigate to "/", this code is executed when the proper DOM is not there yet, and by the time you navigate to "/map", the code is not re-executed so that's why it fails.

To address this particular issue, proceed as follow :

First you should surround your map-canvas with a {{#constant}} directive.

<template name="map">
    {{#constant}}
        <div id="map-canvas"></div>
    {{/constant}}
</template>

This will tell Meteor to NOT rerender anything inside this block helper : it won't mess up with Google Maps widget that doesn't need reactivity and rerendering anyway. If you don't do this, whenever a reactive source changes in the page and cause your DOM to refresh, it might wipe out the map-canvas div to replace it with a new one (that's basically what rerendering does) and ruin Google Maps own stuff.

Then put your Google Maps initialization code inside a Template.map.rendered callback.

Template.map.rendered=function(){
    var initializeOnlyOnce=_.once(function(){
        // Google Maps initialization code goes here
    });
    initializeOnlyOnce();
};

To be sure that it will get called only once by Template.map rendering, we use underscore.once (http://underscorejs.org/#once). You won't need the addDomListener window.load stuff because by the time this code runs the page has loaded and we're ready to perform Google Maps rendering immediatly.

Tell me if it solves your problem, I haven't tested this code but this should get you starting on where to go, because at the moment you can't prevent Meteor to serve all of your files at startup, and serving specific files to a specific page is not the way to go because there is no such concept of "page" in Meteor.

These things are quite tedious at the moment but I've heard that new Meteor UI will make it much simpler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top