Qichao Dong
Qichao Dong

Reputation: 364

Google map contained in meteor Template is rendered twice

I have the following template:

<template name="test">
  {{#isolate}}
    <div id="map_canvas" style="width:50%; height:50%"></div>
  {{/isolate}}
</template>

In my test.js (from https://developers.google.com/maps/documentation/javascript/tutorial#HelloWorld) :

function initialize(){
  var mapOptions = {
    center: new google.maps.LatLng(-34.397, 150.644),
    zoom: 8,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  var map = new google.maps.Map($("#map_canvas")[0], mapOptions);
}

Template.test.rendered = function(){
    initialize();
  //*** The following is the workaround I am using:***
  // if (! this.initialized){
  //   initialize();
  //   this.initialized = true;
  // }
};

The problem is: without the workaround shown in the commented code section, the template is always rendered twice (as initialize() is run). It's both shown in console logs (logging code not shown here) and also visible from the map flashing once (which is not acceptable).

The reason, I am guessing, is from the following events happending:

  1. the template is rendered, with $('#map_canvas') generated as a simple div element (no map attached);
  2. google map api returns aync-ly and modifies $('#map_canvas');
  3. somehow Meteor detects the change, and in spite of {{#isolate}}, decides to render the whole template once again (this is shown in log);
  4. initialize() is called again, within Template.test.rendered.

My questions:

  1. why?
  2. if this is what happened, why is Meteor only rendering twice, instead of infinite times?
  3. solution?

3 questions and lots of thanks!

Upvotes: 3

Views: 1553

Answers (1)

Tom Coleman
Tom Coleman

Reputation: 3037

The template is probably being rendered twice due to the outer context that contains {{> test}} being re-rendered. There's a variety of reasons why this might happen, but usually it's just that it renders initially without subscription data, and then a second time when the data has loaded.

Anyway, in your specific case, I think what you want is a {{#constant}} wrapper around your google map, rather than an {{#isolate}}.

NOTE: {{#constant}} areas do get re-rendered if (for whatever reason) the surrounding context is re-rendered. However the new version gets thrown away rather than replaced in the DOM. So just be careful in you rendered callback to only do something the first time.

Upvotes: 4

Related Questions