Estoy usando la API de Google Map para recuperar información de ciudad + estado / región de una búsqueda de código postal. El problema es que en algunos casos una búsqueda de código postal no recuperará el nombre de una ciudad. Un ejemplo es 92625 (EE. UU.).

var g = new GClientGeocoder();
g.setBaseCountryCode('US');
g.getLocations('92625', function(response){
    if (response) {
        var place = response.Placemark[0];
        var state = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
        var city  = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
        GLog.write("City = "+city+" : State/Region = "+state+" : Country = " + g.getBaseCountryCode());
    }
});

En ciertos casos, como se mencionó anteriormente, no habrá un nombre de ciudad en el resultado, por lo que habrá un error indefinido para la ciudad, porque la Localidad clave no existe. Este error impide que se ejecute el resto del script.

Pude remediarlo ...

    if (place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality != null)
        var city  = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
    else
        var city = '';

... pero esto me tiene paranoico sobre un error similar para otras teclas. Por ejemplo: si AdministrativeArea no está definido, la declaración IF anterior también causaría un error indefinido. Entonces, ¿debería verificar para ver si cada clave / nodo existe? Parece ser un enfoque desordenado porque algunas de estas claves tienen más de 5 niveles de profundidad ... ¿hay alguna manera más fácil de hacerlo, tal vez algún método JQuery con el que no estoy familiarizado?

15
Seth 15 jul. 2009 a las 07:15

4 respuestas

La mejor respuesta

Alternativamente, puede hacer una función que le proporcione valores predeterminados:

function valueOrDefault(val, def) {
    if (def == undefined) def = "";
    return val == undefined ? def : val;
}

Y luego úsalo así:

var place = response.Placemark[0];
var state = valueOrDefault(place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName);
var city  = valueOrDefault(place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName);

Personalmente, creo que es un poco más agradable de escribir, que la propuesta de p00ya, aunque es un poco loco manipulando objetos indefinidos ... uno podría cambiarlo a esto:

function drill(p, a) {
 a = a.split(".");//add this
 for (i in a) {
  var key = a[i];
  if (p[key] == null)
    return '';
  p = p[key];
 }
 return p;
}
var obj = {foo:{bar:{baz:"quux"}}};
var s = drill(obj, "foo.bar.baz"));//and you can use a simple property chain
9
Benjamin Manns 3 sep. 2012 a las 22:41

Estás viendo solo el primer resultado que te da el geocodificador:

var place = response.Placemark[0];

getLocations () devuelve una lista de varios resultados. Si el primero no lo tiene, uno de los siguientes resultados casi seguro lo tendrá.

0
Chris B 15 jul. 2009 a las 15:06

Me gusta el enfoque de back2dos, pero creo que podría mejorarse para no fallar con ReferenceError s:

function jPath(obj, a) {
    a = a.split(".");
    var p = obj||{};
    for (var i in a) {
        if (p === null || typeof p[a[i]] === 'undefined') return null;
        p = p[a[i]];
    }
    return p;
}

// Tests
var a = {b:{c:'Hello World!'}, c:null};

console.log(jPath(a, 'b.c'));   // Hello World
console.log(jPath(a, 'b.d'));   // null
console.log(jPath(a, 'e.f.g')); // null
console.log(jPath(a, 'c'));     // null

var z;
console.log(jPath(z, 'c'));     // null

Este tipo de función es ideal para validar estructuras de retorno JSON profundas de servicios AJAX como freebase o YQL.

3
Marc 30 dic. 2012 a las 11:44

Podría usar una función que "profundice" en todos esos niveles de anidación, por defecto en la cadena vacía si no puede llegar tan lejos.

function drill(p, a) {
 for (i in a) {
  var key = a[i];
  if (p[key] == null)
    return '';
  p = p[key];
 }
 return p;
}
var obj = {foo:{bar:{baz:"quux"}}};
var s = drill(obj, ["foo", "bar", "baz"]));
3
p00ya 15 jul. 2009 a las 04:03