2009-07-15 6 views
15

J'utilise l'API Google Map pour récupérer les informations sur la ville + l'état/la région à partir d'une recherche de code postal. Le problème est que, dans certains cas, une recherche de code postal ne récupère pas le nom d'une ville. Un exemple est 92625 (États-Unis).Vérifier si les clés/nœuds JSON existent

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

Dans certains cas, comme mentionné ci-dessus, il n'y aura pas un nom de ville dans le résultat donc il y aura une erreur non définie pour la ville, car la clé Localité n'existe pas. Cette erreur empêche le reste du script de s'exécuter.

j'ai pu y remédier par ...

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

... mais cela m'a paranoïaque à propos d'une erreur similaire pour les autres clés. Par exemple: si AdministrativeArea n'est pas défini, l'instruction IF ci-dessus entraînerait également une erreur non définie. Alors devrais-je vérifier pour voir si chaque clé/nœud existe? Semble être une approche désordonnée, car certaines de ces touches ont plus de 5 niveaux de profondeur ... y a-t-il un moyen plus simple d'y parvenir, peut-être une méthode JQuery que je ne connais pas?

Répondre

9

Sinon, vous pouvez faire une fonction, qui vous donne par défaut:

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

Et utiliser ensuite comme ceci:

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

Personnellement, je pense qu'il est un peu plus agréable à écrire, que la proposition de p00ya, même si c'est un peu hacker bidouiller dans des objets indéfinis ... on pourrait peut-être changer à ceci:

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 
3

Vous pouvez utiliser une fonction qui "fore" vers le bas à travers tous ces niveaux d'imbrication, par défaut à la chaîne vide si elle ne peut pas aller aussi loin.

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"])); 
0

Vous regardez seulement le premier résultat le géocodage vous donne:

var place = response.Placemark[0]; 

getLocations() retourne une liste de plusieurs résultats. Si le premier ne l'a pas, l'un des prochains résultats le sera certainement.

+0

Dans l'exemple ci-dessus, il n'y a toujours qu'un seul résultat pour 92625. – Seth

3

J'aime l'approche de back2dos mais je pense qu'il pourrait être amélioré pour ne pas échouer avec 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 

Ce type de fonction est grande pour la validation des structures de retour JSON profonde des services AJAX tels que freebase ou YQL.

Questions connexes