Search code examples
javascriptpolymerweb-component

using HTMLImports.whenReady not working in chrome


I have a web component using HTMLImports.whenReady to make sure that certain things get fired in the correct timing, and the problem is this fixed the bugs I was having in IE and Firefox, but now it is not working in chrome.

so on the page of the site i have this:

<link rel="import" href="/static/template/components/result-map.html">
<link rel="import" href="/static/template/components/result-options.html">
<link rel="import" href="/static/template/components/advanced-modal.html">
<link rel="import" href="/static/template/components/map-modal.html">

<div class="row-fluid">
    <div id="component" class="span12">
        <div class="well">
            <!-- TMPL_IF Listings -->
            <div class="row-fluid">
                <small><em>Press a map marker for more information</em></small><br />
                <result-map></result-map>
            </div>
            <!-- /TMPL_IF -->
        </div>
    </div>
</div>

<script>    
/*GENERATE MAP MARKERS*/
HTMLImports.whenReady(function(){
    <!-- TMPL_IF Listings -->   
        <!-- TMPL_LOOP Listings -->
            <!-- TMPL_IF have_geocode -->
                markers.push({
                    latLng: [<!-- TMPL_VAR latitude -->, <!-- TMPL_VAR longitude -->],
                    data: '...',
                    options: {
                        icon: "/static/images/mapmarker.png",
                        title: "<!-- TMPL_VAR street_no --> <!-- TMPL_VAR street -->, <!-- TMPL_VAR city -->, <!-- TMPL_VAR state --> <!-- TMPL_VAR zip -->"
                    }
                });
            <!-- TMPL_ELSE -->
                markers.push({
                    address:"<!-- TMPL_VAR street_no --> <!-- TMPL_VAR street -->, <!-- TMPL_VAR city -->, <!-- TMPL_VAR state --> <!-- TMPL_VAR zip -->",
                    data: '...',
                    options: {
                        icon: "/static/images/mapmarker.png",
                        title: "<!-- TMPL_VAR street_no --> <!-- TMPL_VAR street -->, <!-- TMPL_VAR city -->, <!-- TMPL_VAR state --> <!-- TMPL_VAR zip -->"
                    }
                });
            <!-- /TMPL_IF -->
        <!-- /TMPL_LOOP -->
    <!-- /TMPL_IF -->
});
</script>

and then the polymer webcomponent looks like this

<dom-module id="result-map">
<template>
    <div id="map_canvas"></div>
</template>

<script>
var markers = [];

HTMLImports.whenReady(function(){
    $('#map_canvas').gmap3({
        map:{
            options:{ 
                streetViewControl: false,
                mapTypeId: google.maps.MapTypeId.ROADMAP,
                mapTypeControl: false,
                mapTypeControlOptions: {
                center: true,
                zoom: 10,
            },
         }
        },
        marker:{
            values: markers,
            options:{
                draggable: false
            },
            events:{
                click: function(marker, event, context){
                    $('#map-modal').empty().append(context.data).modal('show');
                    $(this).gmap3('get').panTo(marker.getPosition());
                },
            },
        },
        autofit:{maxZoom: 16},
    })
});

Polymer({
    is: 'result-map',

    // Fires when an instance of the element is created
    created: function() {},

    // Fires when the local DOM has been fully prepared
    ready: function() {},

    // Fires when the element was inserted into the document
    attached: function() {},

    // Fires when the element was removed from the document
    detached: function() {},

    // Fires when an attribute was added, removed, or updated
    attributeChanged: function(name, type) {}
});
</script>
</dom-module>

The idea behind this is that the map markers have to be made in the loop server side so I then, and at times through out the site the markers are different, and then load them in to a common webcomponent and push the markers into the "marker" object.

When I originally wrote the script I was firing on document.ready and this would cause IE and FF to not load the markers as the VAR was not created until the the component was loaded, so changing to HTMLImports.whenReady this allowed this to happen, but now breaks chrome for some reason.

Re-reading my question, I want to be specific, the object markers is empty in chrome but not in IE an FF with what is above.


Solution

  • At the time you register your callback to HTMLImports.whenReady in Chrome, the event has already fired. Your callback won't get called because it was registered too late. With your solution, you catch Chrome in the first assignment to markers and the polyfilled browsers in the second one. Another way to handle this problem in general is this:

    if (HTMLImports.ready) {
       doStuff();
    } else {
       HTMLImports.whenReady(doStuff);
    }
    

    This way, you ensure that the doStuff function will be called exactly once.