Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map works once / CSS height issues #58

Open
vhuerta opened this issue Jul 16, 2015 · 27 comments
Open

Map works once / CSS height issues #58

vhuerta opened this issue Jul 16, 2015 · 27 comments
Labels

Comments

@vhuerta
Copy link

vhuerta commented Jul 16, 2015

Hi im using iron router to load a template than contains a GoogleMap, it works perfectly the first time you navigate to the the route, but when access again, the map not work. Heres the code

Template.appraisalGeolocation.created = function() {
    GoogleMaps.load({v: '3', key: '12345', libraries: 'geometry'});
    GoogleMaps.ready('geolocation', geolocation.readyHandler);
}
@foysalit
Copy link

facing the same issue. when I switch route and get back to the map it seems to load but the map's content isn't visible. I say it seems to load because the control options of the map is visible.
selection_004

@vhuerta
Copy link
Author

vhuerta commented Jul 23, 2015

Its a problem re creating the map, i solved it hidding the map instead create it again, but i do it by my self with no plugins :/

@dburles
Copy link
Owner

dburles commented Jul 24, 2015

Hey @vhuerta @foysalit this seems like a bug, happy to take a look if you can provide a simple reproduction app. See: https://github.com/meteor/meteor/wiki/Contributing-to-Meteor#reporting-a-bug-in-meteor

@boogieprod
Copy link

Hi, I'm still a newbie in the world of web programming (started last November) and specially on Meteor framework (started to learn on May) and I'm facing the same issue trying to program a simple website for an university project. The re-route process doesn't work. The best solution would probably reside in a some kind of page destroyed so Google maps API would be properly re-loaded once the user would re-route to the map-container. I've read the entire GitHub article about how to report a bug and I feel that it's kind of painful given the current issue. Let me know if this was helpful or not because as I said I don't have a lot of experience in the world of web programming.

Thanks,
Love your work
Boogieprod

@dburles
Copy link
Owner

dburles commented Aug 6, 2015

I should have some time over the next couple days to take a look into things.

@foysalit
Copy link

foysalit commented Aug 6, 2015

Sorry for the late response.
I don't think this is a bug in the package. Here's my scenario -

Reason

I was setting the height of the map container with js on template rendered hook.

Debugging

I looked up usual google map rendering issues and most of them seemed to be caused by map's height. Packages from other stacks such as angular google map suggests you to apply a fixed css height on the map container to overcome issues like this. so I decided to take apply the css fix.

Fix

I removed the js bit that sets the height dynamically and put the map template inside a div with class .home-map like this - <div class="home-map">{{> googleMap name="homeMap" options=homeMapOptions}}</div>. Then applied the following css on that class.

.home-map {
    position: absolute;
    top: 50px;
    right: 0;
    left: 0;
    bottom: 0;
}

This seems to solve the issue and render the map accurately no matter how many times I move around different routes.

@foysalit
Copy link

foysalit commented Aug 6, 2015

@dburles If you still think it might be caused by the package itself and willing to find a fix for it, let me know and I'd be happy to submit a complete bug report as instructed by the contribution guide.

@dburles
Copy link
Owner

dburles commented Aug 6, 2015

I've just created a super basic app, but I can't reproduce the bug. Find it here: https://github.com/dburles/map-bug-58. @boogieprod and @vhuerta perhaps look over this code to see where you might be going wrong?

@foysalit
Copy link

foysalit commented Aug 6, 2015

I have forked map-bug-58 to show what was going on with my above mentioned scenario. Please check it out if you think this might help - foysalit/map-bug-58@9cee1d0

@boogieprod
Copy link

Hey guys I've tried with absolute positioning and fixed height/width attributes but it does the same.
I made this repo https://github.com/boogieprod/map-bug-58 to show the issue that I have. Read README. @dburles Your sample app is working perfectly fine and is using the exact same code than mine so I'm wondering what could be the issue.

Thanks again

@dburles
Copy link
Owner

dburles commented Aug 7, 2015

Hey @boogieprod your issue is with the use of the momentum package, try remove the momentum block helper (surrounding yield) in master_layout.html. I believe the issue is related in that the map is not able to calculate positioning correctly. That's an issue outside of this package itself and to do with google maps.

@boogieprod
Copy link

@dburles Your right, thanks for your time, it's highly appreciated. Do you have any idea how I could work around that issue with Momentum? (I like the transition because Meteor renders things WAY TOO FAST :) that sometimes it needs a little delay for a good end-user experience) Thanks a lot.

@dburles
Copy link
Owner

dburles commented Aug 7, 2015

Hmm not really sure without digging into it a bit more. Perhaps you could add the percolate:momentum-iron-router package to https://github.com/dburles/map-bug-58 as a simplified reproduction and open a bug report over here: https://github.com/percolatestudio/momentum-iron-router/

@boogieprod
Copy link

Will do, I'll edit previous post with solution so if someone encounters the same issue, he'll know what to do without disturbing peace.

Once again, thanks so much for you're help, I knew Aussies were good people. (Oi Oi Oi)

@dburles
Copy link
Owner

dburles commented Aug 7, 2015

:) Good luck

@sahina
Copy link

sahina commented Aug 8, 2015

I am running into the same issue like this. If I set the the height of the map container to a fixe height, map loads every time. If I set it with javascript, map shows grey as in @foysalit 's screen shot.

Here is the working set up. Map loads every time I come back to /map route

// .css
.map-container {
  width: auto;
  height: 500px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

// client
Meteor.startup(function() {
  GoogleMaps.load();
});

// template
Template.map.onCreated(function() {
  GoogleMaps.ready('searchMap', function(map) {
    // ...
  }
}

This does NOT work.

// .css
.map-container {
  width: auto;
  /* height: 500px; */
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}

// client
Meteor.startup(function() {
  GoogleMaps.load();
});

// template
Template.map.onCreated(function() {
  GoogleMaps.ready('searchMap', function(map) {
    // ...
  }
}

var resizeMap = function() {
  var neg = $('.main-header').outerHeight() + $('.main-footer').outerHeight() + $('.content-header').outerHeight();
  var window_height = $(window).height();
  var height = window_height - neg - 30;

   $('.map-container').css("height", height);
}

Template.map.onRendered(function() {
  resizeMap();
  $(window).resize(_.throttle(resizeMap, 200));
});

Issue is the map container height. I know this is not the your package's issue but any pointer would help.

Thanks

@ldong
Copy link

ldong commented Oct 4, 2015

I had the similar issue, instead of putting googleMap in a template,

  <div class="map-container">
    {{> googleMap name="exampleMap" options=exampleMapOptions}}
  </div>

Just create a DOM

<div class="map" id="defaultMap"></div>

then call explicitly based on different event triggers.

Template.YourTemplateName.events({
  "click #map": function(e, t){
    if (!GoogleMaps.maps.defaultMap){
      console.log("Creating new defaultmap");
      GoogleMaps.create({
        name: 'defaultMap',
        element: document.getElementById('defaultMap'),
        options: {
          center: new google.maps.LatLng(37.72,-122.45),
          zoom: 8
        }
      });
    }
});

@dcworldwide
Copy link

Same issue for me.

It definitely seems related to the height property. I need to set it explicitly in CSS before anything renders. This is a bit of a pain, as it makes responsive layouts harder. In may case, i'm using flexbox, but it doesn't work with google maps for this reason.

I've tried deferring the instantiation of the component until the template DOM is fully rendered as follows. Yet even with this lazy approach, the issue persists.

Template.X.rendered = function () {

    let instance = Template.instance();
    let self = this;

    Meteor.defer(() => {

        let mapId = "abc";

        GoogleMaps.ready(mapId, function (map) {
            instance.map = map;
        });

        // Load google maps api if required
        if (!GoogleMaps.loaded()) {
            GoogleMaps.load({v: '3', libraries: 'geometry'}); //, key: '12345', lib: ,places
        }

        this.autorun(c => {

            if (GoogleMaps.loaded()) {

                // Terminate computation
                c.stop();

                // Instantiate ui component
                GoogleMaps.create({
                    name: mapId,
                    element: self.$(".map-container")[0],
                    options: {
                        mapTypeId: google.maps.MapTypeId.ROADMAP,
                        center: new google.maps.LatLng(-37.8136, 144.9631),
                        zoom: 1
                    }
                });
            }
        })
    });
};

@cdeadlock
Copy link

I am having a lot of trouble with map re-rendering.

I have had to put in a weird hack to allow re-rendering

{{#unless noRender}}
  ... most of a template ...
{{/unless}}

Session.set("noRender", true);
.. do stuff ..
Tracker.flush();
Session.set("noRender", false);

This was the only way (that I have found so far) to get certain things to re-render in meteor it seems, but I am not sure how to re-render maps when necessary.

I have 2 different maps, each in a modal activated by a button.

When I use the blaze template for maps it seems only the first map that I load's onReady is called.

When I am creating them dynamically with GoogleMaps.create then the div they reside in is re-rendered to blank when I re-render. How do I re-render a map to its element dynamically?

If i try to GoogleMaps.create a new instance every time I re-render, it will create multiple custom UI elements. I tried deleting GoogleMaps.maps.mymap and that doesn't seem to remove the existing instance. Is there a way to remove instances and re-create them? Sounds really inefficient.

Is there a proper way to "re-render" map instances?

@walkerrandolphsmith
Copy link

percolate:momentum-iron-router fixed the issue I had with google maps rendering gray when using iron router and momentum. +1

@dburles dburles changed the title Map works once Map works once / CSS height issues Dec 1, 2015
@mattiemoon
Copy link

Hello all.

I've been banging my head against this problem for the last couple of nights and I wondered if anybody had found a solution or workaround?

I see the following behaviour:

  1. The first time I access the route in question, my Google map renders perfectly.
  2. If I then move elsewhere in the app, and then return to the same route later, the map container renders portions of the map (grey background, Google logo, terms and conditions, etc.) but the map itself is missing
  3. If I make a code change that triggers a hot swap, the map renders fine
  4. If the data source that the map is rendering changes, the map refreshes and renders fine

Here's my template:

<template name="customerOrders">
  {{> header headerTitle="Order history" headerClass="navbar-black" showBackButton="true"}}

  <div id="myContent" class="hide">
    {{#each allCustomerOrders}}
      <div class="order-map-container" id="order-map-{{_id}}-container">
        {{> googleMap name=this._id options=(mapOptions this)}}
      </div>
      <div class="container-fluid">
        <div class="row">
          <div class="col-xs-3">DRIVER</div>
          <div class="col-xs-6">{{toFormattedDateAndTime date}}</div>
          <div class="col-xs-3"><p class="text-right">{{to2dp price}}</p></div>
        </div>
        <div class="row">
          &nbsp;
        </div>
      </div>
    {{/each}}
  </div>
</template>

...and the JS file backing it:

Template.customerOrders.helpers({
  mapOptions : function(order) {
      if (GoogleMaps.loaded()) {
        return {
          options: {
            center: new google.maps.LatLng(order.deliveryAddress.latitude, order.deliveryAddress.longtitude),
            zoom: 14,
            zoomControl: false,
            streetViewControl: false,
            draggable: false,
            mapTypeControl: false
          }
        };
      }
    }
});

...and I've hardcoded the height of the div using CSS:

.order-map-container {
  min-height: 100px;
  height: 100px;
  width: auto;
  margin: 10px;
}

Having studied this thread, and scoured Google for hours, it looks like there's something dodgy - potentially related to iron:router - going on here.

Has anybody had any luck sorting this "map renders once" issue?

Cheers in advance.

@dburles
Copy link
Owner

dburles commented Jan 13, 2016

Hey @mattiemoon have you tried this example app https://github.com/dburles/map-bug-58 maybe comparing it with your app may help you track down the source of the problem

@mattiemoon
Copy link

Hi @dburles,

Thanks for the quick reply. I'll give this a bash later in the week and will report back - thanks again!

@mattiemoon
Copy link

Hello.

The test app helped me find the problem after cutting out reems of code. Turns out a CSS class was causing the problem. From my example above, if I chuck away the following:

<div id="myContent" class="hide">

Everything works fine no matter how may times I leave and re-render the template containing the maps. The "hide" class was going to be used to handle some transition animations, and doesn't actually map to anything concrete yet - my assumption is that code in my router file (that once the styles were defined) was running, and the timing of this versus the maps rendering was causing the problem (speculation again though - I'm new to most of this):

// This one was supposed to hide the current content
Router.onBeforeAction(function() {
  setTimeout(function () {
    $('#myContent').removeClass("fadeIn");
  });

  setTimeout(function () {
    $('#myContent').addClass("hide");   
  });
});

// This one was supposed to reveal the new content
Router.onAfterAction(function() {
  setTimeout(function () {
    $('#myContent').removeClass("hide");
  });

  setTimeout(function () {
    $('#myContent').addClass("animated fadeIn");
  });
});

I'm going to bin that and find another solution for the transitions - I'd much rather have the maps working!

Thanks again for the help @dburles; massively appreciated.

@krishaamer
Copy link

Also having a similar issue when switching back and forward between routes using flow router. The GoogleMaps.ready() seems to run only once and next time it no longer loads the map. Any advice?

@dburles
Copy link
Owner

dburles commented Nov 22, 2016

@krishaamer try this working example it may help you track down the issue in your own app https://github.com/dburles/map-bug-58

@Roshdy
Copy link

Roshdy commented Oct 14, 2017

Workaround:
google.maps.event.trigger(GoogleMaps.maps.map.instance, 'resize');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests