2015-10-01 15 views
5

Ho le seguenti 2 funzioni per inserire, geocodificare e posizionare indicatori in una mappa di google.Google Map Geocoded TypeError in Callback function

Continuo a ricevere uno TypeError: adds[i] is undefined, che ovviamente sta causando il bombardamento del resto della mappa.

Ecco il mio codice:

// 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 E RESTITUZIONE DATI PER aggiunge

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

Qual è 'adds'? – MrUpsidown

+0

un array di informazioni sull'oggetto di posizione e sì è popolato – Kevin

+0

Provare a modificare l'ordine di incremento per (var i = 0; i Alimentador

risposta

1

Una possibilità, passare l'oggetto completo "indirizzo" nella funzione GetLatLng, e da lì nella sua richiamata (in modo da ottenere la chiusura funzione su di esso):

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

Quindi utilizzare in questo modo all'interno della callback (si poteva passare solo l'indice nella matrice anche):

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

frammento di codice:

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>

+0

Grazie amico per l'aiuto con questo. Ora se c'è un modo in cui posso superare questo "limite" di # di segni mostrati, sarò d'oro. Ho un totale di 21 indirizzi da segnare sulla mappa, ma solo 11 stanno mostrando .... nessun errore :) – Kevin

+1

Questa è un'altra domanda, possibile duplicato di [OVER_QUERY_LIMIT nell'API di Google Maps v3: Come faccio una pausa/ritardo in Javascript per rallentarlo?] (Http://stackoverflow.com/questions/11792916/over-query-limit-in-google-maps-api-v3-how-do-i-pause-delay-in-javascript- to-sl) – geocodezip

-1

for(var i = 0; i < aCt - 1; ++i). Devi aggiungere "-1" al tuo ciclo. L'array inizia dall'indice 0 e non 1. È inoltre necessario prestare attenzione all'utilizzo delle funzioni in un ciclo for. All'interno di javascript un ciclo for non ha uno scope da se stesso. Solo le funzioni creano nuovi ambiti.

+0

nessun cambiamento. ottieni ancora l'errore – Kevin

0

Questo sembra un tipico problema di associazione. Nel momento in cui viene richiamato il callback, il valore di adds[i] sarà cambiato. È probabile che il ciclo sia terminato e che i abbia ora un valore di last index + 1, che non punta a nulla. Si noti che potrebbe anche puntare all'indice sbagliato, che non fallirebbe ma utilizzare i dati errati.

È necessario associare localmente il valore di adds[i] per ogni iterazione oppure il callback utilizzerà solo un riferimento a un valore globale. Ci sono molti modi per farlo, qui ce n'è uno semplice in cui continuiamo a passare adds[i] come argomento di funzione.

Sostituire adds[i].address con adds[i] quando si chiama GetLatLng e aggiungere un secondo parametro add al callback:

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

Quindi modificare GetLatLng utilizzare add.address invece di add e aggiungere add alla chiamata di richiamata:

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

Quindi, nella funzione di richiamata, sostituire tutte le istanze di adds[i] con add per utilizzare la variabile locale.

Non ho impostato un test, ma in teoria dovrebbe funzionare.

0

sembra che tu stia complicando le cose. Qualche motivo per cui non puoi farlo?

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