回调函数中的Google Map Geocoded TypeError

时间:2015-10-01 15:04:28

标签: javascript google-maps google-maps-api-3

我有以下2个功能可以在谷歌地图中提取,地理编码和放置标记。

我不断得到TypeError: adds[i] is undefined,这当然会导致地图的其余部分爆炸。

这是我的代码:

// 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返回数据添加

[
{
    "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"
}
]

4 个答案:

答案 0 :(得分:1)

一个选项,将完整的“地址”对象传递给GetLatLng函数,并从那里传递回其回调(因此你可以获得函数闭包):

// 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);
        }
    });
};

然后在回调中使用它(你也可以只将索引传递给数组):

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 concept fiddle

代码段

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 :(得分:0)

这看起来像是典型的绑定问题。当您的回调被调用时,adds[i]的值将发生变化。循环很可能终止,i现在的值为last index + 1,这表示什么都没有。请注意,它也可能指向错误的索引,该索引不会失败但使用错误的数据。

您必须在本地为每次迭代绑定adds[i]的值,否则回调将仅使用对全局值的引用。有多种方法可以解决这个问题,这里有一个简单的方法,我们不断将adds[i]作为函数参数传递。

在调用adds[i].address时将adds[i]替换为GetLatLng,并在回调中添加第二个参数add

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

然后修改GetLatLng以使用add.address而不只是add并将add添加到回调调用中:

// 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;
};

然后在回调函数中,将adds[i]的所有实例替换为add以使用局部变量。

我没有设置测试但理论上应该可行。

答案 2 :(得分:0)

你似乎过于复杂了。有什么理由不能这样做吗?

    String url = Html.fromHtml("http://sexocomcafe1-teste.tempsite.ws/imagensUsuario13/avata/Atra%C3%A7%C3%A3o%20PerigosaRJ_44690132.jpg").toString();
    Picasso.with(this)
   .load(url)
   .into(img);

答案 3 :(得分:-1)

for(var i = 0; i < aCt - 1; ++i)。您需要在for循环中添加“-1”。数组从索引0开始而不是1.您还需要小心使用for循环中的函数。在javascript中,for循环没有自己的范围。只有函数才能创建新的范围。