Reverse Geocoding in Javascript

This was a neat thing I learned recently. We've all done geocoding... pass an address to a web service, like geocoder.us or through the Google Maps API, and get back a coordinate in latitude and longitude, which you can use to search for things nearby (using a database of things with lat/long coordinates and the trusty Haversine Distance formula, get directions, put a marker on a map, etc.)

Recently I've needed to find out a zip code for the person viewing the website. This won't be an exact science, for the obvious reason of desktop computers don't typically have GPS, and IP address geolocating is pretty good for many people but there are those cases where the ISP might assign an IP for Camden to a person in Philadelphia. I have no proof but go along with it. Either way, it will be close enough for what I'm doing.

Basically, all you do is use Google's GeoCoder object, and pass in a google.maps.LatLng object instead an address! Here's how:

var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var coder = new google.maps.Geocoder();
coder.geocode({ 'latLng': latLng }, showLocaleCallback);


Here's all the code:

function initZip() {
if (navigator.geolocation && typeof (navigator.geolocation.getCurrentPosition) == "function") {
navigator.geolocation.getCurrentPosition(geoCodeCallback);
}
}

function geoCodeCallback(position) {
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var coder = new google.maps.Geocoder();
coder.geocode({ 'latLng': latLng }, showLocaleCallback);
}

function showLocaleCallback(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var zip = "";
var res = results[0];
for (var i = 0; i < res.address_components.length; i++) {
if (res.address_components[i].types[0] == "postal_code") {
zip = res.address_components[i].short_name;
}
}

$("[id$=txtZip]").val(zip);
}
}

$(document).ready(initZip);


Be sure to include Google's Map API Javascript and jQuery. These are two cool techs that I really like to work with.

Google's Map API: http://maps.google.com/maps/api/js?sensor=false

Also, if anyone has a pointer on how to more effeciently do this part, I'm all ears:

for (var i = 0; i < res.address_components.length; i++) {
if (res.address_components[i].types[0] == "postal_code") {
zip = res.address_components[i].short_name;
}
}

Experiments in Javascript: Multicast Delegate

There are quite a few blog posts out there about "doing window.onload the right way", albeit from 2007. I looked over them, and took issue with the hard-coded feel that they had.  For instance, a function that returns a function, but takes two functions, and no more, as arguments. I came across an instance where this just wasn't acceptable, according the new dogma of Javascript programmers out there, which is to write as few lines as possible. I explored new ways of accomplishing this.

First and foremost, don't use window.onload :) attachEvent and addEventListener are there for this exact purpose. Let's take a trip back 5 years and pretend this was relevant for window.onload. However it is still relevant for Javascript in general.

The problem of just outright setting window.onload to your function, is that it will overwrite whatever window.onload was set to previously. This can lead to malfunctioning pages that are very difficult to debug. That was the theory of all of the posts about "doing window onload the right way".

function foo(){ alert("foo"); }
window.onload = foo;

// somewhere else on the page, maybe 1000 lines below
function bar() { alert("bar"); }

window.onload = bar;

You can deduce that "foo" will not be alerted. This would be bad if our foo actually did something, like start a video of a cat doing silly things. Devastating. How can they both work?!

The first accepted method is to build a function inline that combines two functions:

window.onload = function(){ foo(); bar(); }
This will work if that's the only time window.onload is set. You can't call window.onload explicitly inside of window.onload unless you like infinite loops. However, storing the referenced function and updating window.onload to the new function is fair. With that knowledge, let's continue our investigation.

The current method out there to get the previous window.onload and the additional function to call correctly looks like this:

function doublecast(fn1, fn2){
return function(){
if (typeof(fn1) == "function")
fn1();
if (typeof(fn2) == "function")
fn2();}
}

You would use this method to add to the window's onload functionality like so:

window.onload = doublecast(window.onload, foo);
If you needed to add more functions, you would do so in successive calls to "doublecast":

window.onload = doublecast(window.onload, foo);
window.onload = doublecast(window.onload, bar);

or through the ugly method of

window.onload = doublecast(window.onload, function(){ foo(); bar(); });
jQuery has made this acceptable, but it's still ugly! And the successive calls are not line-number friendly. Obviously, after reading John Resig's "Learning Advanced JavaScript", I feel I am ready to build a more appropriate and clean function.

function multicast(){
if (arguments == null || arguments.length == 0) return function(){ };

var fns = [], j = 0;
for (var i = 0; i < arguments.length; i++){
if (typeof(arguments[i]) == "function")
fns[j++] = arguments[i];
}

return function(){
for (var i = 0; i < fns.length; i++)
fns[i]();
};
}

Our new code looks like this:
window.onload = multicast(window.onload, foo, bar);
window.onload could have been set previously, and we don't care. We know we've defined two functions in the current module (say, an ASP.NET control or some other type of view) and it will work, so long as no one after us sets window.onload = myAwesomeLoadFunction; which would overwrite it... I guess no solution is completely future proof.
Discuss in the comments, please.

PromoteJS again

JS Array .sort

Just need to do that occasionally because w3schools sucks.