Google Map Geocoded TypeError in callback function

I have the following 2 functions for inserting, geocoding and placing markers on a google map.

I keep getting TypeError: adds[i] is undefined , which of course makes the rest of the map bomb.

Here is my code:

 // Place Markers on the Map var PlaceMarkers = function (iw, adds, gc) { var image = {url: "http://meatmysite.com/Images/star2.png", size: new google.maps.Size(24, 24)}; var aCt = adds.length; for(var i = 0; i < aCt; ++i) { GetLatLng(gc, adds[i].address, function(pos) { if(pos) { var ipop = '<h1>' + adds[i].title + '</h1>'; // <----- TypeError: adds[i] is undefined if(!isBlank(adds[i].url)){ ipop += '<a href="' + adds[i].url + '" target="_blank">' + adds[i].url + '</a><br />'; } ipop += '<div class="map_item_content" id="mi_content' + i + '">' + adds[i].content + '</div>'; if(!isBlank(adds[i].mainphone)){ ipop += '<br /><strong>Phone:</strong> <a href="tel:'+adds[i].mainphone+'">' + adds[i].mainphone + '</a>'; } if(!isBlank(adds[i].mainemail)){ ipop += '<br /><strong>Email:</strong> <a href="mailto:'+adds[i].mainemail+'">' + adds[i].mainemail + '</a>'; } console.log('HEY NOW: ' + pos.toString() + ' - Location Found!'); var mark = new google.maps.Marker({title: adds[i].title, position: pos, map: map, icon: image, html: ipop}); google.maps.event.addListener(mark, 'click', function(){ iw.setContent(this.html); iw.open(map, this); }); } }); } }; // Get Lat/Lng Location var GetLatLng = function(gc, add, f) { var ret = ''; gc.geocode({'address': add}, function(res, status) { if (status == 'OK') { f(res[0].geometry.location); console.log('Found Here: ' + ret.toString()); } }); return -1; }; 

DEMO RETURN DATA To add

 [ { "address": "1 My Street Gilbert, AZ 85234", "title": "My Title 1", "url": "http://www.myurl.com/", "mainphone": null, "mainemail": null, "content": "1 My Street<br />Gilbert, AZ 85234" }, { "address": "2 My Street North Richland Hills, TX 76182", "title": "My Title 2", "url": null, "mainphone": null, "mainemail": null, "content": "2 My Street<br />North Richland Hills, TX 76182" } ] 
+5
source share
4 answers

One parameter, pass the complete "address" object to the GetLatLng function, and from there to its callback (so that you close the function on it):

 // Get Lat/Lng Location var GetLatLng = function (gc, add, f) { gc.geocode({ 'address': add.address }, function (res, status) { if (status == 'OK') { f(res[0].geometry.location, add); } }); }; 

Then use it like it does in the callback (you can only pass the index to the array):

 GetLatLng(gc, adds[i], function (pos, add) { if (pos) { var ipop = '<h1>' + add.title + '</h1>'; if (!isBlank(add.url)) { ipop += '<a href="' + add.url + '" target="_blank">' + add.url + '</a><br />'; } ipop += '<div class="map_item_content" id="mi_content' + i + '">' + add.content + '</div>'; if (!isBlank(add.mainphone)) { ipop += '<br /><strong>Phone:</strong> <a href="tel:' + add.mainphone + '">' + add.mainphone + '</a>'; } if (!isBlank(add.mainemail)) { ipop += '<br /><strong>Email:</strong> <a href="mailto:' + add.mainemail + '">' + add.mainemail + '</a>'; } console.log('HEY NOW: ' + pos.toString() + ' - Location Found!'); var mark = new google.maps.Marker({ title: add.title, position: pos, map: map, icon: image, html: ipop }); google.maps.event.addListener(mark, 'click', function () { iw.setContent(this.html); iw.open(map, this); }); } }); 

proof of conceptual scripts

code snippet:

 var geocoder = new google.maps.Geocoder(); var map; var infoWindow = new google.maps.InfoWindow(); function initialize() { map = new google.maps.Map( document.getElementById("map_canvas"), { center: new google.maps.LatLng(37.4419, -122.1419), zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP }); PlaceMarkers(infoWindow, adds, geocoder); } google.maps.event.addDomListener(window, "load", initialize); // Place Markers on the Map var PlaceMarkers = function(iw, adds, gc) { var bounds = new google.maps.LatLngBounds(); var image = { url: "http://meatmysite.com/Images/star2.png", size: new google.maps.Size(24, 24) }; var aCt = adds.length; for (var i = 0; i < aCt; ++i) { GetLatLng(gc, adds[i], function(pos, add) { if (pos) { var ipop = '<h1>' + add.title + '</h1>'; // <----- TypeError: adds[i] is undefined if (!isBlank(add.url)) { ipop += '<a href="' + add.url + '" target="_blank">' + add.url + '</a><br />'; } ipop += '<div class="map_item_content" id="mi_content' + i + '">' + add.content + '</div>'; if (!isBlank(add.mainphone)) { ipop += '<br /><strong>Phone:</strong> <a href="tel:' + add.mainphone + '">' + add.mainphone + '</a>'; } if (!isBlank(add.mainemail)) { ipop += '<br /><strong>Email:</strong> <a href="mailto:' + add.mainemail + '">' + add.mainemail + '</a>'; } console.log('HEY NOW: ' + pos.toString() + ' - Location Found!'); var mark = new google.maps.Marker({ title: add.title, position: pos, map: map, // icon: image, html: ipop }); bounds.extend(mark.getPosition()); map.fitBounds(bounds); google.maps.event.addListener(mark, 'click', function() { iw.setContent(this.html); iw.open(map, this); }); } }); } }; // Get Lat/Lng Location var GetLatLng = function(gc, add, f) { gc.geocode({ 'address': add.address }, function(res, status) { if (status == 'OK') { f(res[0].geometry.location, add); } }); }; var adds = [{ "address": "1 My Street Gilbert, AZ 85234", "title": "My Title 1", "url": "http://www.myurl.com/", "mainphone": null, "mainemail": null, "content": "1 My Street<br />Gilbert, AZ 85234" }, { "address": "2 My Street North Richland Hills, TX 76182", "title": "My Title 2", "url": null, "mainphone": null, "mainemail": null, "content": "2 My Street<br />North Richland Hills, TX 76182" }]; function isBlank(str) { return (!str || /^\s*$/.test(str)); } 
 html, body, #map_canvas { height: 100%; width: 100%; margin: 0px; padding: 0px } 
 <script src="https://maps.googleapis.com/maps/api/js"></script> <div id="map_canvas"></div> 
+1
source

This seems like a typical binding problem. By the time your callback is called, the value of adds[i] will be changed. It is likely that the loop is complete and i now has the value last index + 1 , which does not indicate anything. Please note that it may also indicate an invalid index that will not work, but use invalid data.

You must bind the value adds[i] locally for each iteration or the callback will use a reference to the global value. There are several ways to do this, here is a simple example in which we continue to pass adds[i] as an argument to the function.

Replace adds[i].address with adds[i] when calling GetLatLng and add the second add parameter to the callback:

 GetLatLng(gc, adds[i], function(pos, add) { ... }); 

Then change GetLatLng instead of add.address instead of add and add add to the callback call:

 // Get Lat/Lng Location var GetLatLng = function(gc, add, f) { var ret = ''; gc.geocode({'address': add.address}, function(res, status) { if (status == 'OK') { f(res[0].geometry.location, add); console.log('Found Here: ' + ret.toString()); } }); return -1; }; 

Then, in the callback function, replace all adds[i] instances with add to use the local variable.

I did not configure the test, but it should theoretically work.

0
source

you seem too much. Any reason you can't do this?

 // Place Markers on the Map var PlaceMarkers = function (iw, adds, gc) { var aCt = adds.length; for(var i = 0; i < aCt; ++i) { var obj=adds[i]; GetLatLng(gc, obj) } }; // Get Lat/Lng Location var GetLatLng = function(gc, obj) { var ret = ''; gc.geocode({'address': obj.address}, function(res, status) { if (status == 'OK') { var pos=res[0].geometry.location; var ipop = '<h1>' + obj.title + '</h1>'; // <----- TypeError: adds[i] is undefined if(!isBlank(obj.url)){ ipop += '<a href="' + obj.url + '" target="_blank">' + obj.url + '</a><br />'; } ipop += '<div class="map_item_content" id="mi_content">' + obj.content + '</div>'; if(!isBlank(obj.mainphone)){ ipop += '<br /><strong>Phone:</strong> <a href="tel:'+obj.mainphone+'">' + obj.mainphone + '</a>'; } if(!isBlank(obj.mainemail)){ ipop += '<br /><strong>Email:</strong> <a href="mailto:'+obj.mainemail+'">' + obj.mainemail + '</a>'; } console.log('HEY NOW: ' + pos.toString() + ' - Location Found!'); var mark = new google.maps.Marker({title: obj.title, position: pos, map: map, html: ipop}); google.maps.event.addListener(mark, 'click', function(){ iw.setContent(this.html); iw.open(map, this); }); } else { console.log("geocoder problem!") } }); }; 
0
source

for(var i = 0; i < aCt - 1; ++i) . You need to add “-1” to the for-loop. The array starts at index 0, not 1. You also need to be careful when using functions in a for loop. Inside javascript for-loop has no scope from itself. Only functions create new areas.

-1
source

Source: https://habr.com/ru/post/1232731/


All Articles