I've been having a problem very similar to this
However that persons question was never answered and my situation is subtly different.
I'm trying to add a click event to my map that will change the center of the map to the location of the click. My code to do this works great, but it only works once and then when I click again I get this error:
angular-google-maps.js:6815 Uncaught TypeError: Cannot read property 'click' of undefined
Here is my map object:
vm.map = {
center: {
latitude: l.latitude,
longitude: l.longitude
},
zoom: 13,
events: {
click: function(map, event, coords) {
vm.map = {
center: {
latitude: coords[0].latLng.lat(),
longitude: coords[0].latLng.lng()
},
};
$scope.apply();
}
}
};
And here's my html:
<ui-gmap-google-map center="location.map.center" zoom="location.map.zoom" draggable="true" options="tabLocations.map.options" events=location.map.events>
<ui-gmap-search-box template="'scripts/components/tab-locations/searchbox.tpl.html'" events="location.map.searchbox.events" parentdiv="'searchbox-container'"></ui-gmap-search-box>
<ui-gmap-marker ng-if="location.active" idKey="1" coords="location" options="{draggable: false, icon: 'images/icons/gps-marker-active.svg'}"></ui-gmap-marker>
<ui-gmap-marker ng-if="!location.active" idKey="1" coords="location" options="{draggable: false, icon: 'images/icons/gps-marker-inactive.svg'}"></ui-gmap-marker>
</ui-gmap-google-map>
After your first click you are redefining a brand new map with no click event:
vm.map = {
center: {
latitude: coords[0].latLng.lat(),
longitude: coords[0].latLng.lng()
},
};
This is overriding all the previous properties you had set before, which includes click.
Use setCenter instead:
click: function(map, event, coords) {
var latLng = new google.maps.LatLng(latitude: coords[0].latLng.lat(), latitude: coords[0].latLng.lng());
vm.map.setCenter(latLng);
}
Reference: Google Maps API
Related
How to catch Google Map Event with listener
I want to be able to use bounds_changes event with listner. However, in Vue.js, I cannot get it working; even though the event happens, it is not able to catch the event.
So, I want to add custom event listner using addListener, but I do not know where to start.
Any advice or suggestion would be appreciated. Thank you in advance.
Below is my code :
const mapElement = document.getElementById('map');
const mapOptions = {
center: {
lat: 37.5005794,
lng: 126.9837758
},
zoomControl : false,
zoom: 10,
disableDefaultUI: true
};
const map = google.maps.Map(mapElement, mapOptions);
google.maps.event.addListenerOnce(map, 'bounds_changed', function() {
var bounds = map.getBounds(),
northEast = {
'lat' : bounds.getNorthEast().lat(),
'lng' : bounds.getNorthEast().lng()
},
southWest = {
'lat' : bounds.getSouthWest().lat(),
'lng' : bounds.getSouthWest().lng()
};
console.log(northEast)
});
You may use a global event bus in scenario like this
const EventBus = new Vue();
google.maps.event.addListenerOnce(map, "bounds_changed", function() {
// ...
EventBus.$emit("bounds_changed", {
bounds,
northEast,
southWest
});
});
new Vue({
el: "#app",
created() {
EventBus.$on("bounds_changed", ({ bounds, northEast, southWest }) => {
// put your operation in vue here
});
}
});
I have an overlay placed on a google map:
function CustomerMarker(map) {
this.Map = map;
this.setMap(map);
}
GoogleMap = new google.maps.Map(document.getElementById("map"), {
zoom: 16,
canZoom: false,
center: { lat: lat, lng: lng },
mapTypeControl: false,
streetViewControl: false,
scaleControl: false,
clickableIcons: false
});
CustomMarker.prototype = new google.maps.OverlayView();
CustomMarker.prototype.onAdd = function () {
//Some code
};
CustomMarker.prototype.draw = function () {
//Some code
};
CustomMarker = new CustomMarker(GoogleMap);
Which works fine, and the overlay shows up, however is issue arises when I try to remove that
CustomMarker.setMap(null)
I get an error and the marker remains
Error: this.remove is not a function
pz#https://maps.googleapis.com/maps-api-v3/api/js/30/1/overlay.js:1:251
rk#https://maps.googleapis.com/maps-api-v3/api/js/30/1/overlay.js:2:476
_.pg.prototype.map_changed/<#https://maps.googleapis.com/maps/api
/js?key=AIzaSyBCiIPv6fgrRVn3veTJeP6ihfhrw8AXwbY:125:662
_.G#https://maps.googleapis.com/maps/api/js?key=AIzaSyBCiIPv6fgrRVn3veTJeP6ihfhrw8AXwbY:51:447
_.pg.prototype.map_changed#https://maps.googleapis.com/maps/api/js?key=AIzaSyBCiIPv6fgrRVn3veTJeP6ihfhrw8AXwbY:125:636
Db#https://maps.googleapis.com/maps/api/js?key=AIzaSyBCiIPv6fgrRVn3veTJeP6ihfhrw8AXwbY:37:103
_.k.set#https://maps.googleapis.com/maps/api/js?key=AIzaSyBCiIPv6fgrRVn3veTJeP6ihfhrw8AXwbY:101:728
_.jd/<#https://maps.googleapis.com/maps/api/js?key=AIzaSyBCiIPv6fgrRVn3veTJeP6ihfhrw8AXwbY:55:317
The documentation for OverlayView states:
You must implement three methods: onAdd(), draw(), and onRemove().
I don't see an implementation for onRemove.
I am trying to display markers after the map is displayed. I am unable to do so.. regardless of any error. I have assured that the snapshot is with the data and marker array is nicely created. is there any logical error?? please help.
var apps = angular.module('appa',['firebase','uiGmapgoogle-maps']);
apps.controller('mainCtrl', function($firebaseObject,$scope){
var ref = firebase.database().ref();
var marker = [];
ref.once("value")
.then(function(snapshot)
{
snapshot.forEach(function(child)
{
var mark = {
id: child.child("Id").val(),
coords: {
latitude: child.child("Lat").val(),
longitude: child.child("Long").val()
},
options: { title: child.child("Alt").val() }
};
marker.push(mark);
});
});
$scope.map = {
center:
{
latitude: 67,
longitude: 24
},
zoom: 3
};
});
<body ng-app="apps">
<div id="map_canvas" ng-controller="mainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom">
<ui-gmap-marker ng-repeat="m in marker" coords="m.coords" options="m.options" idkey="m.id">
</ui-gmap-marker>
</ui-gmap-google-map>
</div>
<!--example-->
</body>
oh! I hot the answer my self. It was a simple mistake. I did not defined marker array in $scope. Therefore views were not getting what var marker is. I corrected it
I'm using Angular UI Google Maps and am trying to get the latlng from where the map is clicked. Currently the map is returning a response, but without latlng. Please see my code below:
Controller
$scope.map = {
center: {
latitude: 45, longitude: -73
},
zoom: 8,
events: {
"click": function (event) {
console.log(event.latlng);
}
}
};
html
<ui-gmap-google-map events="map.events" center='map.center' zoom='map.zoom'></ui-gmap-google-map>
response from click:
Ln {gm_bindings_: Object, __gm: Wh, gm_accessors_: Object, mapTypeId: "roadmap", center: df…}__e3_: Object__gm: Whbounds: undefinedcenter: dfcontrols: Array[14]data: ghfeatures: UgetOptions: function () {gm_accessors_: Objectgm_bindings_: ObjectmapDataProviders: "Map data ©2014 Google"mapTypeId: "roadmap"mapTypes: DgmapUrl: "http://maps.google.com/maps?ll=45,-73&z=8&t=m&hl=en-US&gl=US&mapclient=apiv3"overlayMapTypes: lgstreetView: Uhtilt: 0tosUrl: "http://www.google.com/intl/en-US_US/help/terms_maps.html"uiGmap_id: "4b1e4213-59cd-4016-baac-2aa2af44fe1a"zoom: 8__proto__: c
If you need any more code please let me know.
Thanks
Turns out that the event will return it as an array from a third argument, please see fix below. I hope this helps someone :)
$scope.map = {
center: {
latitude: 45, longitude: -73
},
zoom: 8,
events: {
"click": function (event, a, b) {
console.log(a);
console.log(b);
}
}
};
I want to remove event listener for click added by:
var events = {
click: function () {
// crazy stuff here :- )
}
};
$(where).gmap3(
{
events: events
}
);
Need something like:
$(where).gmap3().removeEventListener('click');
Didn't realize gmap3 was a wrapper library. Ill remove the duplicate comment.
Browsing through the gmaps3 documentation, I did not see anything specific to remove listeners with the libraries functions, but you can grab the marker with action: 'get' and then clear the listener.
Here is a example that a altered from the documentation. I added a name and tag property to the markers and at the end of this script I remove the mouseover listener from the marker with tag:'2'. For some reason this library is fickle and wants both the name and tag property to find the marker.
$('#test').gmap3({
action: 'init',
options: {
center: [46.578498, 2.457275],
zoom: 5
}
}, {
action: 'addMarkers',
markers: [
{
name : 'marker',
tag: '1',
lat: 48.8620722,
lng: 2.352047,
data: 'Paris !'},
{
name : 'marker',
tag: '2',
lat: 46.59433,
lng: 0.342236,
data: 'Poitiers : great city !'},
{
name : 'marker',
tag: '3',
lat: 42.704931,
lng: 2.894697,
data: 'Perpignan ! GO USAP !'}
],
marker: {
options: {
draggable: false
},
events: {
mouseover: function(marker, event, data) {
var map = $(this).gmap3('get'),
infowindow = $(this).gmap3({
action: 'get',
name: 'infowindow'
});
if (infowindow) {
infowindow.open(map, marker);
infowindow.setContent(data);
} else {
$(this).gmap3({
action: 'addinfowindow',
anchor: marker,
options: {
content: data
}
});
}
},
mouseout: function() {
var infowindow = $(this).gmap3({
action: 'get',
name: 'infowindow'
});
if (infowindow) {
infowindow.close();
}
}
}
}
});
//get the marker by name and tag
var mark = $('#test').gmap3({
action: 'get',
name:'marker',
tag: '2'
});
//remove the event listener
google.maps.event.clearListeners(mark, 'mouseover');
Here is an example of this script working: http://jsfiddle.net/5GcP7/. The marker in the middle will not open an infowindow when moused over.
I solved this problem in different way:
var events = {
click: function () {
if (P.settings.mapPinActive === false) {
return;
}
// crazy stuff here :- )
}
};
Instead of detaching and attaching events, global properties in settings object.