snazzy-info-window icon indicating copy to clipboard operation
snazzy-info-window copied to clipboard

`getMap/setMap is not a function` error when markers are clicked or opened

Open matthewmcvickar opened this issue 6 years ago • 14 comments

Here's my code for initializing the map and its markers and infowindows. Markers are being added just fine, but clicking on the marker throws a marker.getMap is not a function error, and calling open() on the info window returns a marker.setMap is not a function error.

It seems the Snazzy Info Window object can't access the marker object it has been assigned.

The Code:


// Google Maps defaults.
const mapOptions = {
  center: { lat: 45.526970, lng: -122.678152 },
  disableDefaultUI: true,
  disableDoubleClickZoom: true,
  scrollwheel: false,
};

// Build map.
function initMap(map) {
  const embeddedMapContainer = $(map).find('.map__embedded-map')[0];
  const markers = $(map).data('map-markers');

  // Start a Google Map.
  var googleMap = new google.maps.Map(embeddedMapContainer, mapOptions);

  // Add and handle interaction for markers.
  for (var markerData of markers) {

    // Add marker to map.
    var marker = new google.maps.Marker({
      map: googleMap,
      position: {
        lat: markerData.lat,
        lng: markerData.lng
      }
    });

    // Initialize an info window.
    var info = new SnazzyInfoWindow({
      marker: marker,
      content: markerData.description,
      wrapperClass: 'map__marker-popup',
      maxWidth: 250,
      openOnMarkerClick: true,
      closeWhenOthersOpen: true,
      showCloseButton: false
    })

    // Open the info window.
    info.open();
  }
}

The Error:

Uncaught TypeError: this.setMap is not a function at e.value (snazzy-info-window.min.js:1)

matthewmcvickar avatar Dec 28 '17 20:12 matthewmcvickar

After a lot of experimenting, I got this to work by changing my import SnazzyInfoWindow from 'snazzy-info-window to const SnazzyInfoWindow = require('snazzy-info-window') and moving it inside my initMap() function. Maybe something is still wrong with the way v1.1.1 is handling ES6 imports?

matthewmcvickar avatar Dec 28 '17 21:12 matthewmcvickar

i got it to work when i call google maps api without the params "async defer"

Liverson avatar Mar 24 '18 08:03 Liverson

Hi @matthewmcvickar can help me, I have the same error as you, but I can not fix it. I have this code, where I charge Google Maps. When I try to create and open the "info-window" I get the same error as you. Thx

  import * as SnazzyWindow from 'snazzy-info-window';  

  private scriptLoadingPromise: Promise<void>;

  private loadScriptLoadingPromise() {
    const googleMapsScript = window.document.createElement('script');
    googleMapsScript.async = true;
    googleMapsScript.defer = true;
    googleMapsScript.type = 'text/javascript';
    googleMapsScript.src = this.getGoogleMapsApiURL();
    this.scriptLoadingPromise = new Promise<void>((onResolve: Function, onReject: Function) => {
      (<any>window)['afterLoadMap'] = () => {
        onResolve();
      };
      googleMapsScript.onerror = (currentError: Event) => {
        onReject(currentError);
      };
    });
    window.document.body.appendChild(googleMapsScript);
  }

  initMap(mapHtmlElement: HTMLElement, options: google.maps.MapOptions): Promise<void> {
    return this.onReady().then(() => {
      this.googleMapsManager = new GoogleMapsManager(mapHtmlElement, options);
    });
  }

  constructor() {
    this.loadScriptLoadingPromise();
  }

  onReady(): Promise<void> {
    return this.scriptLoadingPromise;
  }

avechuche avatar Apr 15 '18 01:04 avechuche

@avechuche I think you need to switch the ES6 import function to another bundling method, like the require() I suggest above, which would be supported by RequireJS, Node.js, or Browserify.

matthewmcvickar avatar Apr 16 '18 18:04 matthewmcvickar

I managed to solve this issue using dynamic import

const SnazzyInfoWindow = await import('snazzy-info-window')

But you need to do it after google scripts are fetched

eddyLazar avatar Apr 21 '18 07:04 eddyLazar

I resolved this by replacing: <script src="https://maps.googleapis.com/maps/api/js?key=NotMyKey&callback=initMap&sensor=false" async defer></script> to: <script src="https://maps.googleapis.com/maps/api/js?v=3"></script>

Also replace initMap function with $(function () {

manoj7shekhawat avatar Jun 05 '18 09:06 manoj7shekhawat

@manoj7shekhawat But without async defer page will wait until maps.googleapis.com scripts are loaded. Usually it's not a good idea.

eddyLazar avatar Jun 05 '18 09:06 eddyLazar

May sure you are importing the Google maps API before the snazzy windo js

This worked for me:

michaelmarsland avatar Jun 08 '18 22:06 michaelmarsland

Hi @matthewmcvickar ,

I am having the same issue as you, did try your technique but seems I couldn't make it work. would you like to share with us wehere the const SnazzyInfoWindow = require('snazzy-info-window') was implemented in your js code ? screenshot 170

Here is my simplified codepen:

anthonysalamin avatar Oct 28 '18 16:10 anthonysalamin

@anthonysalamin I’m really not sure why it isn’t working. This CodePen setup is different than my setup (using Browserify and Babel), so I don't know how to debug it, but the problem you’re seeing in this CodePen seems to be the same one I originally had, so I think it’s the same root bug in this library. We will need someone at Atmist to fix it, I’m afraid (maybe @joelkravets or @adamkrogh?).

matthewmcvickar avatar Oct 28 '18 23:10 matthewmcvickar

@matthewmcvickar, thank you so much for getting back at me though ! I will try digg some more. Never used Browserify nor Babel before, I'm just using codepen to write custom code I then implement in my webflow projects.

anthonysalamin avatar Oct 29 '18 10:10 anthonysalamin

Same issues here. Getting very very tired with Google maps

jimmykane avatar Feb 13 '20 13:02 jimmykane

Run your browserify scripts first and then include Google Maps. In your callback function require Snazzy once Google Maps is ready. E.g.

window.initMap = () => {

    var SnazzyInfoWindow = require('snazzy-info-window');

    // Do everything else

}

This works for me where all other solutions above didn't.

texelate avatar Apr 16 '20 10:04 texelate

Fix from @texelate worked for me.

samhadr avatar Feb 02 '21 20:02 samhadr