Home > database >  Google Maps API V2 open infowindow error using local storage data
Google Maps API V2 open infowindow error using local storage data

Time:09-20

I am integrating local storage into the map functionality for GeoDirectory for WordPress. The functionality stores the map marker and WordPress post data in storage, then loads it in when a user revisits the map page after viewing a listing. A live example can be viewed here.

I have successfully stored the map marker's and WordPress data in storage using the storeUserMarker function and can retrieve it when page the page loads using loadUserMarker. I have included both functions below.

function storeUserMarker(item, map_canvas) {
  let markerId, markerTitle, markerContent, markerIcon, markerAnchor, markerPosition;
  markerId = item.id;
  markerTitle = item.title;
  markerContent = html;
  markerIcon = item.icon = {
    url: item.icon,
    origin: new google.maps.Point(0, 0),
    anchor: item.anchorPoint
  };
  markerAnchor = item.anchorPoint;
  markerPosition = item.position;
  localStorage.setItem( 'id', markerId );
  localStorage.setItem( 'title', markerTitle );
  localStorage.setItem( 'content', markerContent );
  localStorage.setItem( 'icon', JSON.stringify(markerIcon) );
  localStorage.setItem( 'anchor', JSON.stringify(markerAnchor) );
  localStorage.setItem( 'position', JSON.stringify(markerPosition) );
}

function loadUserMarker(item, map_canvas) {
  let markerId = localStorage.getItem( 'id' );
  let markerTitle = localStorage.getItem( 'title' );
  let markerContent = localStorage.getItem( 'content' );
  let markerIcon = JSON.parse(localStorage.getItem( 'icon' ));
  let markerAnchor = JSON.parse(localStorage.getItem( 'anchor' ));
  let markerPosition = JSON.parse(localStorage.getItem( 'position' ));
  let marker = {
    id: markerId,
    title: markerTitle,
    icon: markerIcon,
    anchorPoint: markerAnchor,
    position: markerPosition,
    visible: true,
    clickable: true
  };
  // console.log(marker);
  // console.log(markerContent);
  // const infowindow = new google.maps.InfoWindow({
  //   content: markerContent,
  // });
  // console.log(infowindow);
  let loading = '<div id="map_loading"></div>';
  gd_infowindow.open(jQuery.goMap.map, marker);
  gd_infowindow.setContent(loading);
  setTimeout(function() {
    jQuery(document.body).trigger('geodir_map_infowindow_open', [{
      map: 'google',
      canvas: map_canvas,
      content: markerContent
    }]);
  }, 100);
}

When the page loads, the local storage items are loaded from marker and markerContent, but the following error is shown in the console: Uncaught TypeError: a.get is not a function. It seems to be triggered by the gd_infowindow object method. When I comment it out, no errors are displayed, though the code does not function.

The issue seems to be a conflict with the Google Maps JS file loaded from https://maps.googleapis.com/maps/api/js?key=hidden&libraries=places&language=en&ver=2.2.9:300. I have included the supposed conflict code below.

_.Gg.prototype.open=function(a,b){var c=b;b={};"object"!==typeof a||!a||a instanceof _.zg||a instanceof _.lf?(b.map=a,b.anchor=c):(b.map=a.map,b.shouldFocus=a.shouldFocus,b.anchor=c||a.anchor);a=(a=Bg(b.anchor))&&a.get("map");a=a instanceof _.lf||a instanceof _.zg;b.map||a||console.warn("InfoWindow.open() was called without an associated Map or StreetViewPanorama instance.");var d=_.u(Object,"assign").call(Object,{},b);a=d.map;b=d.anchor;c=this.set;var e=d.map;var f=d.shouldFocus;e="boolean"===typeof f?

I am quite new to using Google Maps with this WordPress plugin, so I am unsure of why the infowindow is not executing correctly. It does work outside of the loadUserMarker function when run through the create_marker function. The full create_marker function is included below.

function create_marker(item, map_canvas) {
  if (window.gdMaps == 'osm') {
    return create_marker_osm(item, map_canvas);
  }
  var map_options = eval(map_canvas);
  jQuery("#"   map_canvas).goMap();
  gd_infowindow = (typeof google !== 'undefined' && typeof google.maps !== 'undefined') ? new google.maps.InfoWindow({
    maxWidth: 200
  }) : null;
  if (item.lt && item.ln) {
    var marker_id, title, icon, cs;
    marker_id = item['m'];
    title = geodir_htmlEscape(item['t']);
    cs = item['cs'];
    icon = item['icon'] ? item['icon'] : geodir_params.default_marker_icon;
    iconW = item['w'] ? parseFloat(item['w']) : 0;
    iconH = item['h'] ? parseFloat(item['h']) : 0;
    iconMW = geodir_params.marker_max_width ? parseFloat(geodir_params.marker_max_width) : 0;
    iconMH = geodir_params.marker_max_height ? parseFloat(geodir_params.marker_max_height) : 0;
    /* Some svg files has dimensions with different unit */
    if (geodir_params.resize_marker && ( iconW < iconMW || iconH < iconMH ) && icon.substr((icon.lastIndexOf('.') 1)).toLowerCase() == 'svg') {
        iconW = iconW * 10;
        iconH = iconH * 10;
    }
    if (geodir_params.resize_marker && iconW > 5 && iconH > 5 && ((iconMW > 5 && iconW > iconMW) || (iconMH > 5 && iconH > iconMH))) {
        resizeW = iconW;
        resizeH = iconH;
        resize = false;

        if (iconMH > 5 && resizeH > iconMH) {
            _resizeH = iconMH;
            _resizeW = Math.round(((_resizeH * resizeW) / resizeH) * 10) / 10;

            resizeW = _resizeW;
            resizeH = _resizeH;
            resize = true;
        }

        if (iconMW > 5 && resizeW > iconMW) {
            _resizeW = iconMW;
            _resizeH = Math.round(((_resizeW * resizeH) / resizeW) * 10) / 10;

            resizeW = _resizeW;
            resizeH = _resizeH;
            resize = true;
        }
        if (resize && resizeW > 5 && resizeH > 5) {
            icon = {
                url: icon,
                scaledSize: new google.maps.Size(resizeW, resizeH),
                origin: new google.maps.Point(0, 0),
                anchor: new google.maps.Point((Math.round(resizeW / 2)), resizeH)
            };
        }
    }
    var latlng = new google.maps.LatLng(item.lt, item.ln);
    var marker = jQuery.goMap.createMarker({
        id: marker_id,
        title: title,
        position: latlng,
        visible: true,
        clickable: true,
        icon: icon,
        label: cs,
        zIndex: (item.zIndex ? item.zIndex : 0),
        zIndexOrg: (item.zIndexOrg ? item.zIndexOrg : 0)
    });
    bounds.extend(latlng);
    // Adding a click event to the marker
    google.maps.event.addListener(marker, 'spider_click', function() { // 'click' => normal, 'spider_click' => Overlapping Marker Spiderfier
        var marker_url = map_options.map_marker_ajax_url;
        is_zooming = true;
        jQuery("#"   map_canvas).goMap();
        var preview_query_str = '';
        if (item.post_preview) {
            preview_query_str = '&post_preview='   item.post_preview;
        }
        marker_url = marker_url   ''   item.m;
        post_data = marker_url.indexOf('?') === -1 ? '?' : '&';
        post_data  = '_wpnonce='   map_options._wpnonce;
        if (map_options.bubble_size) {
            post_data  = '&small=1';
        }
        if (map_options.map_marker_url_params) {
            post_data  = map_options.map_marker_url_params;
        }
        var loading = '<div id="map_loading"></div>';
        gd_infowindow.open(jQuery.goMap.map, marker);
        gd_infowindow.setContent(loading);
        jQuery.ajax({
            type: "GET",
            url: marker_url   post_data,
            cache: false,
            dataType: "json",
            error: function(xhr, error) {
                alert(error);
            },
            success: function(response) {
                jQuery("#"   map_canvas).goMap();
                html = typeof response == 'object' && response.html ? geodir_htmlEscape(response.html) : '';
                gd_infowindow.setContent(html);
                gd_infowindow.open(jQuery.goMap.map, marker);
                setTimeout(function() {
                    jQuery(document.body).trigger('geodir_map_infowindow_open', [{
                        map: 'google',
                        canvas: map_canvas,
                        content: html
                    }]);
                }, 100);
                /** Custom code begin **/
                storeUserMarker(marker, html);
                /** Custom code end **/
                // give the map 1 second to reposition before allowing it to reload
                setTimeout(function() {
                    is_zooming = false;
                }, 1000);
            }
        });
        return;
      });
      // Overlapping Marker Spiderfier
      jQuery.goMap.oms.addMarker(marker);
      // Adding a visible_changed event to the marker
      google.maps.event.addListener(marker, 'visible_changed', function() {
        gd_infowindow.close(jQuery.goMap.map, marker);
      });
      return true;
  } else {
      //no lat & long, return no marker
      return false;
  }
}

Any help is greatly appreciated.

CodePudding user response:

The issue is that you are trying to use plain old JavaScript objects (POJOs) not a google.maps.Marker, google.maps.Point, etc. here...

gd_infowindow.open(jQuery.goMap.map, marker);

Where maker is a POJO...

  let marker = {
    id: markerId,
    title: markerTitle,
    icon: markerIcon,
    anchorPoint: markerAnchor,
    position: markerPosition,
    visible: true,
    clickable: true
  };

To fix you will need to create an actual marker/position, etc - e.g. the marker needs to something like...

  let marker = jQuery.goMap.createMarker({
    id: markerId,
    title: markerTitle,
    icon: markerIcon, // this will need to be a google.maps.icon too I presume
    anchorPoint: new google.maps.Point(anchor.x, anchor.y), // or something 
    position: new google.maps.LatLng(position.lat, position.lng), // or something
    visible: true,
    clickable: true
  });

However it isn't clear what format you store your "markerPosition", "markerIcon", etc in - but you should probably store values ("latitude", "longitude", "x", "y", "imageUrl", etc) separately so that you can recreate the google.map.whatever objects when needed.

The key thing here is you need to serialise to store - then deserialize back to actual google.map.whatever objects to use them.

The error Uncaught TypeError: a.get is not a function is simply because your marker is a POJO not a google.maps.Marker

  • Related