2

I'm writing acceptance tests using Selenium to test an application that uses the Google Maps API. In order to test the map marker placement I'm using un-optimized markers and unique title attributes to allow me to target the marker elements (from Selenium with XPath queries).

I have come across an issue wherein calling google.maps.Map.fitBounds() causes markers to be removed from the DOM when un-optimized markers are used. You have to repeatedly call fitBounds() for this to happen. This only happens with un-optimized markers and the application itself works as expected.

I've written a short test script to replicate in the browser: please run the below.

I did also create a fiddle.

I've seen nothing pertinent in the API docs.

Any help would be great.

<html>
  <head>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
    <style type="text/css">
    #container {
      width: 800px;
      height:500px;
    }
    </style>
  </head>
  <body>
    <button id="show">Show</button>
    <button id="hide">Hide</button>
    <div id="container"></div>
    <script type="text/javascript">

      // Repeatedly click on 'Hide' then 'Show' (8+ times sometimes).  At some point the markers disappear and not come back - even if the code for showing/hiding markers is entirely commented out.
      // The issue seems to be with the map.fitBounds() call when un-optimized markers are being used.
      // Note - un-optimized markers are needed for targeting marker HTML elements as part of an acceptance test.
      // Replicated on: 45.0.2 Firefox; 49.0.2623.112 m Chrome.

      function changeBounds(boolToggle) {
        //return; // TODO - if you add this line in the problem is fixed.
        var bounds = new google.maps.LatLngBounds();
        var latLng = boolToggle ? new google.maps.LatLng(70, 70) : new google.maps.LatLng(30, 30);
        bounds.extend(marker1.getPosition());
        bounds.extend(marker2.getPosition());
        bounds.extend(latLng);
        map.fitBounds(bounds);
      }

      var mapOptions = {
        center : { lat : 50, lng : 50 },
        zoom: 5,
      };

      var map = new google.maps.Map(document.getElementById("container"), mapOptions);

      var marker1 = new google.maps.Marker({
        position : {
          lat : 51,
          lng : 51,
        },
        title : "MARK1",
        optimized : false
      });

      var marker2 = new google.maps.Marker({
        position : {
          lat : 52,
          lng : 52,
        },
        title : "MARK2",
        optimized : false
      });

      marker1.setMap(map);
      marker2.setMap(map);

      document.getElementById('show').onclick = function() {
        //marker1.setVisible(true); // TODO - The original code was showing/hiding the markers but the issue is replicated without even doing this.
        //marker2.setVisible(true);

        changeBounds(true);
      }

      document.getElementById('hide').onclick = function() {
        //marker1.setVisible(false); // TODO - The original code was showing/hiding the markers but the issue is replicated without even doing this.
        //marker2.setVisible(false);

        changeBounds(false);
      }
    </script>
  </body>
  </html>

Edit: I've reported this as a bug with Google. See https://code.google.com/p/gmaps-api-issues/issues/detail?id=9912

pb149
  • 2,298
  • 1
  • 22
  • 30
  • I got stuck in the minified Gmaps API, but I can say this: the markers physically disappear (their DOM elements), they don't come back if I reset the map for a marker (if you change optimized to true, then run .setMap(map) on the marker it appears back, but if you set it to false and run setMap again it disappears!) and the only way of making the markers appear again is to drag the map a little bit. – Siderite Zackwehdex Apr 17 '16 at 20:08
  • Made the fiddle render the map, saw the issue with it in Chrome – geocodezip Apr 17 '16 at 21:17

2 Answers2

4

I don't know what the problem is, it must be some issue in the Google Maps API, but I have found a solution: use the pan* methods. The best one, for me, was using panBy, which says to the map to pan by x and y pixels. Moving 0 pixels worked fine, so just adding map.panBy(0,0) after fitBounds fixed the vanishing markers.

However, that means losing the nice gradual moving of the map, so instead I used panBy on the idle event. The final solution was to add the following after the creation of the map:

google.maps.event.addListener(map, 'idle', function() {
    map.panBy(0,0);
});

I am sorry, but I don't have enough time to sift through the Google APIs to actually see what the problem is.

What didn't work:

  • marker.setMap (or any other property)
  • making marker draggable or not
  • google.maps.event.trigger(map, 'some_event');

Related:

Community
  • 1
  • 1
Siderite Zackwehdex
  • 6,293
  • 3
  • 30
  • 46
  • 1
    Thanks - the workaround helped. I also filed a bug report with Google: https://code.google.com/p/gmaps-api-issues/issues/detail?id=9912 – pb149 Jun 11 '16 at 20:09
  • Google merged the above Bug thread with this: https://code.google.com/p/gmaps-api-issues/issues/detail?id=5716 Looks like they've accepted the bug and are able to repo it. Hopefully we'll see a fix in the upcoming releases. – CHawk Aug 10 '16 at 17:18
0

Similar to Siderite, I have no idea how to directly fix the bug. However, a workaround that I found is to trigger the "resize" event for the map:

google.maps.event.trigger(google_map, "resize");
CHawk
  • 1,346
  • 5
  • 22
  • 40
  • Are you sure? Because I remember it was one of the first things I tried and it failed. It's even up there in the things that didn't work. – Siderite Zackwehdex Aug 10 '16 at 20:08
  • Yep - it successfully places the markers back on the map for me. However, in some circumstances calling resize messed up the bounds on the map, so it may not be the appropriate solution for everyone. I did not test with triggering any other google map event. – CHawk Aug 10 '16 at 21:29