Question

i still have some problems with javascript closures, and input/output variables.

Im playing with google maps api for a no profit project: users will place the marker into a gmap, and I have to save the locality (with coordinates) in my db.

The problem comes when i need to do a second geocode in order to get a unique pairs of lat and lng for a location: lets say two users place the marker in the same town but in different places, I dont want to have the same locality twice in the database with differents coords.

I know i can do the second geocode after the user select the locality, but i want to understand what am i mistaking here:

// First geocoding, take the marker coords to get locality.
geocoder.geocode(
  {
    'latLng': new google.maps.LatLng($("#lat").val(), $("#lng").val()),
    'language': 'it'
  },
  function(results_1, status_1){
    // initialize the html var inside this closure
    var html = '';
    if(status_1 == google.maps.GeocoderStatus.OK)
    {
      // do stuff here
      for(i = 0, geolen = results_1[0].address_components.length; i != geolen)
      {
        // Second type of geocoding: for each location from the first geocoding,
        // i want to have a unique [lat,lan]
        geocoder.geocode(
          {
            'address': results_1[0].address_components[i].long_name
          },
          function(results_2, status_2){
            // Here come the problem. I need to have the long_name here, and
            // 'html' var should increment.
            coords = results_2[0].geometry.location.toUrlValue();
            html += 'some html to let the user choose the locality';
          }
        );
      }
      // Finally, insert the 'html' variable value into my dom... 
      //but it never gets updated!
    }
    else
    {
      alert("Error from google geocoder:" + status_1)
    }
  }
);

I tryed with:

  // Second type of geocoding: for each location from the first geocoding, i want
  // to have a unique [lat,lan]
  geocoder.geocode(
    {
      'address': results_1[0].address_components[i].long_name
    },
    (function(results_2, status_2, long_name){
      // But in this way i'll never get results_2 or status_2, well, results_2 
      // get long_name value, status_2 and long_name is undefined.
      // However, html var is correctly updated.
      coords = results_2[0].geometry.location.toUrlValue();
      html += 'some html to let the user choose the locality';
    })(results_1[0].address_components[i].long_name)
  );

And with:

  // Second type of geocoding: for each location from the first geocoding, i want to have
  // a unique [lat,lan]
  geocoder.geocode(
    {
      'address': results_1[0].address_components[i].long_name
    },
    (function(results_2, status_2, long_name){
      // But i get an obvious "results_2 is not defined" error (same for status_2).
      coords = results_2[0].geometry.location.toUrlValue();
      html += 'some html to let the user choose the locality, that can be more than one';
    })(results_2, status_2, results_1[0].address_components[i].long_name)
  );

Any suggestion?

EDIT:

My problem is how to pass an additional arguments to the geocoder inner function:

function(results_2, status_2, long_name){
    //[...]
}

becose if i do that with a clousure, I mess with the original parameters (results_2 and status_2)

Was it helpful?

Solution

If I'm understanding you correctly:

Your problem in the first example is that the second (innermost) geocode's callback function (which appends the string to html) will not have executed by the time you reach the line with the comment Finally, insert the 'html' variable value into my dom....

You are effectively launching the second geocode request, and then inserting html before the operation has completed.


Regarding passing an extra argument to the callback, you could always make a function that creates and returns a function:

eg.

function(my_argument)
{
return(function(cb1,cb2) { ... });
}(my_argument_value);

Then you can pass in whatever you want for my_argument_value, and the innermost code (...) will see it as well as the two callback args.

The return value of this function is what you pass as the callback to the geocode call.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top