Dynamicaly adding InfoWindows and Markers on Google Maps V3-Collection of common programming errors
I am having a very annoying issue with Google Map V3 JavaScript API. The problem might be related to my JavaScript code though.
Here is my complete code:
var __mvcGoogleMap;
var __mvcGeocoder;
var markersArray = [];
var infoWindowsArray = [];
function _initializeGoogleMap() {
__mvcGeocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(38.98569417582484, 35.351452857849154);
var myOptions = {
zoom: 6,
center: latlng,
mapTypeId: google.maps.MapTypeId.HYBRID,
panControl: true,
zoomControl: true,
mapTypeControl: true,
scaleControl: true,
streetViewControl: false,
overviewMapControl: true
};
__mvcGoogleMap = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function findOnMap() {
var srchVal = $("#txtMapSearch").val();
__mvcGeocoder.geocode({'address': srchVal}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
actionURL = '/accommodation/HotelsForMap';
actionData = 'lat=' + results[0].geometry.location.lat() + '&lng=' + results[0].geometry.location.lng();
var _latLongs = [];
var _infoWindows = [];
$.ajax({
type: "POST",
url: actionURL,
data: actionData,
success: function (r) {
if (markersArray) {
for (i in markersArray) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
for (var i = 0; i < r.length; i++) {
_latLongs.length = 0;
_infoWindows.length = 0;
_latLongs[i] = new google.maps.LatLng(r[i].LatLong.Latitude, r[i].LatLong.Longitute);
addMarker(_latLongs[i], r[i].Title);
addInfoWindow(r[i].InfoWindow.Content, markersArray[i]);
google.maps.event.addListener(markersArray[i], 'click', function() {
infoWindowsArray[i].open(__mvcGoogleMap, markersArray[i]);
});
}
var _currentPossition = results[0].geometry.location;
__mvcGoogleMap.setCenter(_currentPossition);
__mvcGoogleMap.setZoom(14);
}
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function addMarker(location, title) {
marker = new google.maps.Marker({
position: location,
title: title,
map: __mvcGoogleMap,
draggable: false
});
markersArray.push(marker);
}
function addInfoWindow(content, marker) {
infoWindow = new google.maps.InfoWindow({
content: content
});
infoWindowsArray.push(infoWindow);
}
$(function() {
$.getScript('http://maps.google.com/maps/api/js?sensor=false&callback=_initializeGoogleMap', function() {
$(window).load(_initializeGoogleMap);
});
});
$("#btnMapSearch").click(function() {
findOnMap();
});
Here is the situation: what I am trying to do is that after I initialize the map and search for a place, I get that places LatLang values and send it to my server. Then I get the results back from my server with some hotel info (name, lat, lang, etc).
Then, I set the marker proper places and I attach infoWindow to each marker. Everything works fine except for infoWindows.
When I click a marker, I see this error on browser console window:
Uncaught TypeError: Cannot call method ‘open’ of undefined
Can you please have a look at what I am doing wrong here?
-
You will need to create a closure for the value of
i
so that it is assigned to the enclosed variable at the time each anonymous function is created. If not, as you continue through the loop, the value ofi
will change until the loop exits and it is left holding a value that is the length of your array + 1 (which is always an undefined index), and this is thei
to which all of your anonymous functions refer. Try the following in your AJAX callback loop:google.maps.event.addListener(markersArray[i], 'click', (function(idx) { return function() { infoWindowsArray[idx].open(__mvcGoogleMap, markersArray[idx]); }; })(i));
Originally posted 2013-11-09 23:17:03.