Reputation: 371
I'm trying to submit a query using the postal code to my DB whenever the googlemaps viewport center changes. I know that this can be done with reverse geocoding with something like:
google.maps.event.addListener(map, 'center_changed', function(){
newCenter();
});
...
function newCenter(){
var newc = map.getCenter();
geocoder.geocode({'latLng': newc}, function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
var newzip = results[0].address_components['postal_code'];
}
});
};
Of course, this code doesn't actually work. So I was wondering how I would need to change this in order to extract the postal code from the results array. Thanks
Upvotes: 23
Views: 67738
Reputation: 933
Just search for postal_code
in all types, and return when found.
const address_components = [{"long_name": "2b","short_name": "2b","types": ["street_number"]}, { "long_name": "Louis Schuermanstraat","short_name": "Louis Schuermanstraat", "types": ["route"]},{"long_name": "Gent","short_name": "Gent","types": ["locality","political" ]},{"long_name": "Oost-Vlaanderen","short_name": "OV","types": ["administrative_area_level_2","political"]},{"long_name": "Vlaanderen","short_name": "Vlaanderen","types": ["administrative_area_level_1","political"]},{"long_name": "België","short_name": "BE","types": ["country","political"]},{"long_name": "9040","short_name": "9040","types": ["postal_code"]}];
// address_components = results[0]address_components
console.log({
'object': getByGeoType(address_components),
'short_name': getByGeoType(address_components).short_name,
'long_name': getByGeoType(address_components).long_name,
'route': getByGeoType(address_components, ['route']).long_name,
'place': getByGeoType(address_components, ['locality', 'political']).long_name
});
function getByGeoType(components, type = ['postal_code']) {
let result = null;
$.each(components,
function() {
if (this.types.some(r => type.indexOf(r) >= 0)) {
result = this;
return false;
}
});
return result;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Upvotes: 0
Reputation: 31
i think this is the most accurate solution:
zipCode: result.address_components.find(item => item.types[0] === 'postal_code').long_name;
Upvotes: 0
Reputation: 10142
You can also use JavaScript .find
method which is similar to underscore _.find
method but it is native and require no extra dependency.
const zip_code = results[0].address_components.find(addr => addr.types[0] === "postal_code").short_name;
Upvotes: 4
Reputation: 1
As I got it zip is the last or the one that before last. That why this is my solution
const getZip = function (arr) {
return (arr[arr.length - 1].types[0] === 'postal_code') ? arr[arr.length - 1].long_name : arr[arr.length - 2].long_name;
};
const zip = getZip(place.address_components);
Upvotes: 0
Reputation: 371
Alright, so I got it. The solution is a little uglier than I'd like, and I probably don't need the last for loop, but here's the code for anyone else who needs to extract crap from address_components[]. This is inside the geocoder callback function
// make sure to initialize i
for(i=0; i < results.length; i++){
for(var j=0;j < results[i].address_components.length; j++){
for(var k=0; k < results[i].address_components[j].types.length; k++){
if(results[i].address_components[j].types[k] == "postal_code"){
zipcode = results[i].address_components[j].short_name;
}
}
}
}
Upvotes: 12
Reputation: 122
I think rather than depending on the index it better checks address type key inside the component. I solved this issue by using a switch case.
var address = '';
var pin = '';
var country = '';
var state = '';
var city = '';
var streetNumber = '';
var route ='';
var place = autocomplete.getPlace();
for (var i = 0; i < place.address_components.length; i++) {
var component = place.address_components[i];
var addressType = component.types[0];
switch (addressType) {
case 'street_number':
streetNumber = component.long_name;
break;
case 'route':
route = component.short_name;
break;
case 'locality':
city = component.long_name;
break;
case 'administrative_area_level_1':
state = component.long_name;
break;
case 'postal_code':
pin = component.long_name;
break;
case 'country':
country = component.long_name;
break;
}
}
Upvotes: 2
Reputation: 41
$.each(results[0].address_components,function(index,value){
if(value.types[0] === "postal_code"){
$('#postal_code').val(value.long_name);
}
});
Upvotes: 4
Reputation: 2014
I use this code to get "Postal code" and "locality", but you can use it to get any other field just changing the value of type:
JAVASCRIPT
var address = results[0].address_components;
var zipcode = '';
var locality = '';
for (var i = 0; i < address.length; i++) {
if (address[i].types.includes("postal_code")){ zipcode = address[i].short_name; }
if (address[i].types.includes("locality")){ locality = address[i].short_name; }
}
Upvotes: 2
Reputation: 21
Romaine M. — thanks! If you just need to find the postal code in the first returned result from Google, you can do just 2 loops:
for(var j=0;j < results[0].address_components.length; j++){
for(var k=0; k < results[0].address_components[j].types.length; k++){
if(results[0].address_components[j].types[k] == "postal_code"){
zipcode = results[0].address_components[j].long_name;
}
}
}
Upvotes: 1
Reputation: 159
It seems that nowadays it's better to get it from the restful API, simply try:
https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR_KEY_HERE
Using an AJAX GET call works perfect!
Something like:
var your_api_key = "***";
var f_center_lat = 40.714224;
var f_center_lon = -73.961452;
$.ajax({ url: "https://maps.googleapis.com/maps/api/geocode/json?latlng="+f_center_lat+","+f_center_lon+"&key="+your_api_key,
method: "GET"
})
.done(function( res ) { if (debug) console.log("Ajax result:"); console.log(res);
var zipCode = null;
var addressComponent = res.results[0].address_components;
for (var x = 0 ; x < addressComponent.length; x++) {
var chk = addressComponent[x];
if (chk.types[0] == 'postal_code') {
zipCode = chk.long_name;
}
}
if (zipCode) {
//alert(zipCode);
$(current_map_form + " #postalcode").val(zipCode);
}
else {
//alert('No result found!!');
if (debug) console.log("Zip/postal code not found for this map location.")
}
})
.fail(function( jqXHR, textStatus ) {
console.log( "Request failed (get postal code via geocoder rest api). Msg: " + textStatus );
});
Upvotes: 0
Reputation: 529
In PHP I use this code. Almost in every conditions it works.
$zip = $data["results"][3]["address_components"];
$zip = $index[0]["short_name"];
Upvotes: 1
Reputation: 21
You can also use this code, this function will help to get zip on button click or onblur or keyup or keydown.
Just pass the address to this function.
use google api with valid key and sensor option removed as it doesn't required now.
function callZipAPI(addSearchZip)
{
var geocoder = new google.maps.Geocoder();
var zipCode = null;
geocoder.geocode({ 'address': addSearchZip }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
//var latitude = results[0].geometry.location.lat();
//var longitude = results[0].geometry.location.lng();
var addressComponent = results[0].address_components;
for (var x = 0 ; x < addressComponent.length; x++) {
var chk = addressComponent[x];
if (chk.types[0] == 'postal_code') {
zipCode = chk.long_name;
}
}
if (zipCode) {
alert(zipCode);
}
else {
alert('No result found!!');
}
} else {
alert('Enter proper address!!');
}
});
}
Upvotes: 2
Reputation: 21
//autocomplete is the text box where u will get the suggestions for an address.
autocomplete.addListener('place_changed', function () {
//Place will get the selected place geocode and returns with the address
//and marker information.
var place = autocomplete.getPlace();
//To select just the zip code of complete address from marker, below loop //will help to find. Instead of y.long_name you can also use y.short_name.
var zipCode = null;
for (var x = 0 ; x < place.address_components.length; x++) {
var y = place.address_components[x];
if (y.types[0] == 'postal_code') {
zipCode = y.long_name;
}
}
});
Upvotes: 0
Reputation: 11
Using JSONPath, it's easily done with one line of code:
var zip = $.results[0].address_components[?(@.types=="postal_code")].long_name;
Upvotes: 1
Reputation: 1
return $http.get('//maps.googleapis.com/maps/api/geocode/json', {
params: {
address: val,
sensor: false
}
}).then(function (response) {
var model= response.data.results.map(function (item) {
// return item.address_components[0].short_name;
var short_name;
var st= $.each(item.address_components, function (value, key) {
if (key.types[0] == "postal_code") {
short_name= key.short_name;
}
});
return short_name;
});
return model;
});
Upvotes: 0
Reputation: 952
Using Jquery
var postalObject = $.grep(results[0].address_components, function(n, i) {
if (n.types[0] == "postal_code") {
return n;
} else {
return null;
}
});
$scope.query.Pincode = postalObject[0].long_name;
Upvotes: 0
Reputation: 1630
What I've realized so far is that in most cases the ZIPCODE is always the last value inside each returned address, so, if you want to retrieve the very first zipcode (this is my case), you can use the following approach:
var address = results[0].address_components;
var zipcode = address[address.length - 1].long_name;
Upvotes: 23
Reputation: 1
This simple code works for me
for (var i = 0; i < address.length; i++) {
alert(address[i].types);
if (address[i].types == "postal_code")
$('#postalCode').val(address[i].long_name);
if (address[i].types == "")
$('#country').val(address[i].short_name);
}
Upvotes: 0
Reputation: 562
Using JQuery?
var searchAddressComponents = results[0].address_components,
searchPostalCode="";
$.each(searchAddressComponents, function(){
if(this.types[0]=="postal_code"){
searchPostalCode=this.short_name;
}
});
short_name or long_name will work above
the "searchPostalCode" var will contain the postal (zip?) code IF
and only IF you get one from the Google Maps API.
Sometimes you DO NOT get a "postal_code" in return for your query.
Upvotes: 12
Reputation: 553
You can do this pretty easily using the underscore.js libraray: http://documentcloud.github.com/underscore/#find
_.find(results[0].address_components, function (ac) { return ac.types[0] == 'postal_code' }).short_name
Upvotes: 14
Reputation: 149
places.getDetails( request_details, function(results_details, status){
// Check if the Service is OK
if (status == google.maps.places.PlacesServiceStatus.OK) {
places_postal = results_details.address_components
places_phone = results_details.formatted_phone_number
places_phone_int = results_details.international_phone_number
places_format_address = results_details.formatted_address
places_google_url = results_details.url
places_website = results_details.website
places_rating = results_details.rating
for (var i = 0; i < places_postal.length; i++ ) {
if (places_postal[i].types == "postal_code"){
console.log(places_postal[i].long_name)
}
}
}
});
This seems to work very well for me, this is with the new Google Maps API V3. If this helps anyone, write a comment, i'm writing my script as we speak... so it might change.
Upvotes: 1
Reputation: 21
This takes only two for loops. The "results" array gets updated once we found the first "type" to be "postal_code".
It then updates the original array with the newly found array set and loops again.
var i, j,
result, types;
// Loop through the Geocoder result set. Note that the results
// array will change as this loop can self iterate.
for (i = 0; i < results.length; i++) {
result = results[i];
types = result.types;
for (j = 0; j < types.length; j++) {
if (types[j] === 'postal_code') {
// If we haven't found the "long_name" property,
// then we need to take this object and iterate through
// it again by setting it to our master loops array and
// setting the index to -1
if (result.long_name === undefined) {
results = result.address_components;
i = -1;
}
// We've found it!
else {
postcode = result.long_name;
}
break;
}
}
}
Upvotes: 2
Reputation: 365
In a word, that's a lot of effort. At least with the v2 API, I could retrieve those details thusly:
var place = response.Placemark[0];
var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
myAddress = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName
myCity = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName
myState = place.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName
myZipCode = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.PostalCode.PostalCodeNumber
There has got to be a more elegant way to retrieve individual address_components without going through the looping jujitsu you just went through.
Upvotes: 0