Angular google maps click event: Cannot read property 'click' of undefined - javascript

I'm using angular google maps with ionic framework and trying to get coordinates on click. In view directive is injected like so
<ui-gmap-google-map center="map.center" zoom="map.zoom" dragging="true" options="map.options" events="map.events"></ui-gmap-google-map>
And here is my controller part
angular.extend($scope,
$scope.map = {
center: {latitude: 53.902407, longitude: 27.561621 },
zoom: 15,
options: {
maxZoom: 16,
minZoom: 13,
styles: mapStyles.bright
},
events: {
click: function (mapModel, eventName, originalEventArgs) {
$log.info("user defined event: " + eventName, mapModel, originalEventArgs);
var e = originalEventArgs[0];
var lat = e.latLng.lat(),
lon = e.latLng.lng();
console.log('You clicked here ' + 'lat: ' + lat + ' lon: ' + lon);
//scope apply required because this event handler is outside of the angular domain
$scope.$apply();
}
}
});
Event part is basically copy-pasted from examples in docs. However, when I click it, I get an error
Where did I go wrong?
UPD Somehow $scope.map.events is undefined, although I can, for instance, console.log it and see that it's defined before the error occurs. Same error is happening for all events. For example,
events: {
tilesloaded: function (map) {
$scope.$apply(function () {
$scope.mapInstance = map;
$log.info('tiles loaded');
});
}
}
returns
Uncaught TypeError: Cannot read property 'tilesloaded' of undefined
in console with the same stacktrace.

You have mixed two ways of bringing something into scope; assignment to scope and extending scope. Either extend the $scope with an object (ie not $scope.map =)
and your code becomes...
angular.extend($scope,{
map: {
center: {latitude: 53.902407, longitude: 27.561621 },
zoom: 15,
options: {
maxZoom: 16,
minZoom: 13,
styles: mapStyles.bright
},....
})
or use assignment to scope
$scope.map = {
center: {latitude: 53.902407, longitude: 27.561621 },
zoom: 15,
options: {
maxZoom: 16,
minZoom: 13,
styles: mapStyles.bright
},....
http://moduscreate.com/angularjs-tricks-with-angular-extend/

Related

How to execute InitMap() inside settimeout ionic 4

I'm using ion-segement in my project, I'm using the google map but I got this error:
ERROR TypeError: Cannot read property 'nativeElement' of undefined
here's the code :
#ViewChild('mapElement', { static: true }) mapNativeElement: ElementRef;
initMap() {
this.map = new google.maps.Map(this.mapNativeElement.nativeElement, {
zoom: 4,
disableDefaultUI: true,
center: { lat: 53.0000, lng: 9.0000 },
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
segmentChanged(event){
if(event.detail.value=== 'map'){
setTimeout(() =>
this.initMap()
,5000)
}
}
html:
<div *ngSwitchCase="'map'">
<div #mapElement class="map"></div>
</div>

Using Prototypal Pattern with Creating a Leaflet Map: error with onEachFeature function

I have the following code that I call to create a copy object of map, and initialize the Leaflet map. This works and loads properly. However, the onEachFeature and/or the clickFeature functions are not working properly.
var map = {
mapUrl: "",
maxZoom: 18,
minZoom: 2,
map: L.map('worldMap').setView([51.505, -0.09], 2),
create: function(values) {
var instance = Object.create(this);
Object.keys(values).forEach(function(key) {
instance[key] = values[key];
});
return instance;
},
initLeafletMap: function() {
L.tileLayer(this.mapUrl, {
attribution: '',
maxZoom: this.maxZoom,
minZoom: this.minZoom,
id: 'mapbox.streets'
}).addTo(this.map);
//add continents' outlines
$.getJSON("/static/continents.json",
(function(style, onEachFeature, map) {
return function(continents) {
console.log(typeof(continents));
L.geoJson(continents, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
};
}(this.style, this.onEachFeature, this.map))
);
},
style: function() {
return {
weight: 2,
opacity: 1,
color: 'beige',
dashArray: '3',
fillOpacity: 0
};
},
onEachFeature: function(feature, layer) {
layer.on({
click: this.clickFeature
});
},
clickFeature: function(e) {
do something here();
},
So when I click on the map, I know the onEachFeature function is called, but it does not call clickFeature. Instead I get this error in the console:
leaflet.js:5 Uncaught TypeError: Cannot read property 'call' of undefined
at e.fire (leaflet.js:5)
at e._fireDOMEvent (leaflet.js:5)
at e._handleDOMEvent (leaflet.js:5)
at HTMLDivElement.r (leaflet.js:5)
Much probably simply need to bind the this context when you pass your onEachFeature method as argument of your IIFE to build the callback to your AJAX call:
this.onEachFeature.bind(this)
See also Leaflet- marker click event works fine but methods of the class are undefined in the callback function
BTW you could also attach your click event listener directly on the Leaflet GeoJSON Layer Group instead of doing it for each child layer.

ERROR TypeError: Cannot read property '__e3_' of undefined

I'm developing a web app with angular 6. I integrated google maps but marker click event is returning me an error.
Help me, thanks in advance.
import { } from '#types/googlemaps';
#ViewChild('whereMap') gmapElement: any;
map: google.maps.Map;
marker: google.maps.Marker;
initMapp() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
let location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
this.map = new google.maps.Map(this.gmapElement.nativeElement, {
center: location,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
let marker = new google.maps.Marker({
position: location,
map: this.map,
draggable: true,
animation: google.maps.Animation.DROP,
title: 'Got you!'
});
});
google.maps.event.addListener(this.marker, 'click', () => {
console.log('marker clicked');
});
} else {
alert("Geolocation is not supported by this browser.");
}
}
}
map initialized and marker is working fine, but im unable to fire click event.
i have called the initMapp() in ngOnInit().
The navigator.geolocation.getCurrentPosition is asynchronous, you are likely meeting a race condition. You should move google.maps.event.addListener inside geolocation callback, otherwise you can try to assign event listener before the marker element was created.
Google Maps JavaScript API error message ERROR TypeError: Cannot read property '__e3_' of undefined typically means that you try to assign event to non-existing DOM element.
Try the following
initMapp() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
let location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
this.map = new google.maps.Map(this.gmapElement.nativeElement, {
center: location,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
this.marker = new google.maps.Marker({
position: location,
map: this.map,
draggable: true,
animation: google.maps.Animation.DROP,
title: 'Got you!'
});
google.maps.event.addListener(this.marker, 'click', () => {
console.log('marker clicked');
});
});
} else {
alert("Geolocation is not supported by this browser.");
}
}
I hope this helps!

$http angularJS loop for each object with leaflet issue

I'm making a little app for AngularJS personal training, and i'm getting a few errors.
I receive Json data from an API, and then I want to display amarker for every object I get. The problem is that I have a console error, so I supposed I've made a mistake.
Here goes my controller
toulouseVeloControllers.controller('toulouseVeloListCtrl', ['$scope', '$http',
function($scope, $http) {
angular.extend($scope, {
osloCenter: {},
markers: {},
defaults: {
scrollWheelZoom: false
}
});
$http.get('https://api.jcdecaux.com/vls/v1/stations?contract=toulouse&apiKey=*********************************').success(function(data) {
$scope.bornes = data;
for (var i = 0; i < data.length; i++) {
$scope.markers.osloMarker = {
lat: data[i].position.lat,
lng: data[i].position.lng,
message: data[i].name,
focus: true,
draggable: false
};
$scope.osloCenter = {
lat: data[1].position.lat,
lng: data[1].position.lng,
zoom: 15
};
}
console.log(data.position.lat);
console.log(data.position.lng);
});
}]);
In my map I only have a marker for my last object. And in the console I have "TypeError: Cannot read property 'lat' of undefined"
When I try to display all my object outside of the map, in a list with ng-repeat, I have no problem.
Here go my HTML :
<div ng-controller="toulouseVeloListCtrl">
<leaflet markers="markers" center="osloCenter" style="width: 100%; height: 500px;"></leaflet>
</div>
Any idea of what is wrong ?
Thank you a lot !!
I guess that problem is:
console.log(data.position.lat);
Maybe you should use :
console.log(data[i].position.lat);
And also:
$scope.markers=[];
$scope.osloCenter=[];
for (var i = 0; i < data.length; i++) {
$scope.markers[i].osloMarker = {
lat: data[i].position.lat,
lng: data[i].position.lng,
message: data[i].name,
focus: true,
draggable: false
};
$scope.osloCenter[i] = {
lat: data[1].position.lat,
lng: data[1].position.lng,
zoom: 15
};
}

How to display a heatmap using dburles:google-maps Meteor package?

UPDATE: Code below is fixed as per accepted answer and is confirmed to be working.
I'm a bit stuck with Meteor, please help me out.
I've installed the dburles:google-maps package and got the map to show markers just fine.
Then I tried to display a heatmap and it's causing an error, I can't resolve - "Uncaught InvalidValueError: setMap: not an instance of Map(anonymous function)"
Console output can be seen here - http://improveit.meteor.com/map
Template.map.helpers({
issueMapOptions: function() {
// Make sure the maps API has loaded
if (GoogleMaps.loaded()) {
// Map initialization options
return {
zoom: 13,
center: new google.maps.LatLng(37.774546, -122.433523),
mapTypeId: google.maps.MapTypeId.SATELLITE,
mapTypeControl: false,
panControl: false,
streetViewControl: false
};
}
}
});
Template.map.onCreated(function() {
// We can use the `ready` callback to interact with the map API once the map is ready.
GoogleMaps.ready('issueMap', function(issueMap) {
var issueData = [
new google.maps.LatLng(37.782551, -122.445368),
new google.maps.LatLng(37.757676, -122.405118),
new google.maps.LatLng(37.757039, -122.404346),
new google.maps.LatLng(37.756335, -122.403719),
new google.maps.LatLng(37.755503, -122.403406),
new google.maps.LatLng(37.754665, -122.403242),
new google.maps.LatLng(37.753837, -122.403172),
new google.maps.LatLng(37.752986, -122.403112),
new google.maps.LatLng(37.751266, -122.403355)
];
var issueArray = new google.maps.MVCArray(issueData);
var heatMapLayer = new google.maps.visualization.HeatmapLayer({
data: issueArray,
radius: 20
});
heatMapLayer.setMap(issueMap.instance);
});
});
<template name="map">
<h1>Issue heat map</h1>
<p>This map will display issues and their severity</p>
<div class="map-container">
{{> googleMap name="issueMap" options=issueMapOptions}}
</div>
</template>
Change this line:
heatMapLayer.setMap(issueMap);
to
heatMapLayer.setMap(issueMap.instance);
The setMap method requires a google map instance. the callback of .ready does not directly provide this as it also has an options object for extra convenience.
I confirmed it works on your site:
Template.map.helpers({
issueMapOptions: function() {
// Make sure the maps API has loaded
if (GoogleMaps.loaded()) {
// Map initialization options
return {
zoom: 13,
center: new google.maps.LatLng(37.774546, -122.433523),
mapTypeId: google.maps.MapTypeId.SATELLITE,
mapTypeControl: false,
panControl: false,
streetViewControl: false
};
}
}
});
Template.map.onCreated(function() {
// We can use the `ready` callback to interact with the map API once the map is ready.
GoogleMaps.ready('issueMap', function(issueMap) {
var issueData = [
new google.maps.LatLng(37.782551, -122.445368),
new google.maps.LatLng(37.757676, -122.405118),
new google.maps.LatLng(37.757039, -122.404346),
new google.maps.LatLng(37.756335, -122.403719),
new google.maps.LatLng(37.755503, -122.403406),
new google.maps.LatLng(37.754665, -122.403242),
new google.maps.LatLng(37.753837, -122.403172),
new google.maps.LatLng(37.752986, -122.403112),
new google.maps.LatLng(37.751266, -122.403355)
];
var issueArray = new google.maps.MVCArray(issueData);
var heatMapLayer = new google.maps.visualization.HeatmapLayer({
data: issueArray,
radius: 20
});
heatMapLayer.setMap(issueMap.instance);
});
});
<template name="map">
<h1>Issue heat map</h1>
<p>This map will display issues and their severity</p>
<div class="map-container">
{{> googleMap name="issueMap" options=issueMapOptions}}
</div>
</template>

Categories