1

I have an array of arrays which looks like this:

var data = [["street1", "zipcode1", "city1"], ["street2", "zipcode2", "city2"], ...]

I want to get the lat/lng using Googles Geocoding API of each address and save everything in a new array which should look like this:

var newdata = [["street1", "zipcode1", "city1", lat1, lng1], ["street2", "zipcode2", "city2", lat2, lng2], ...]

So here is how I try to solve the problem:

var newData = [];
function writeNewData(oldArray) {
    for (i = 0; i < oldArray.length; i++) {
        var temp = [];
        var address = "";
        // note: loop 5 times because I want to add 2 new values to each array
        for (j = 0; j < 5; j++) {

            // this gives me the full address as a string
            address += oldArray[i][j] + " ";

            // just copy the old data to the new array
            if (j < 3) {
                temp.push(oldArray[i][j]);
            }

            // add the new data to the array
            if (j == 3) {  
                getLatLng(address);
                var lat = jQuery("#lat").val();
                temp.push(lat);
            } elseif (j == 4) {
                getLatLng(address);
                var lng = jQuery("#lng").val();
                temp.push(lng);
            }
        }
        newData.push(temp);
    }
};

Note: I use Gmaps.js

function getLatLng(myAddress) {
        GMaps.geocode({
            address: myAddress,
            callback: function(results, status) {
                if (status == 'OK') {
                    var loc = [];
                    loc[0] = results[0].geometry.location.lat();
                    loc[1] = results[0].geometry.location.lng();

                    jQuery("#lat").val(loc[0]);
                    jQuery("#lng").val(loc[1]);
                }
            }
        });
}

Since I can't return the lat/lng from inside the Geocode request I thought outputting it inside an html file and just getting the values and writing them to the new array would work.

The output of the lat and lng works but when I try to get the values inside the loop I get an empty string back. I also tried adding a Timeout after calling getLatLng() which gave me the values but it kinda messed up the new array by adding all the new values to the last array in the loop.

Looked like this:

if (j == 3) {  
    getLatLng(address);
    setTimeout(function () {
        var lat = jQuery("#lat").val();
        temp.push(lat);
    }, 200);
}

Anyone have an idea what Im missing here and is there maybe an easier way to accomplish this?

3
  • Are you hitting the async nature of javascript? it takes time to go get the lat / lon and return. And adding a timer delay (in the wrong place, mind you) isn't good coding practice. Commented Jun 14, 2016 at 0:45
  • Yes, I think thats my mistake. Im new to programming so its really quick and dirty. Where would you add the Timer / Timeout? Commented Jun 14, 2016 at 0:47
  • Using a timer / timeout is definitely bad practice. You should do a bit of research and try to understand exactly what when wrong, and the proper way to fix it. Commented Jun 14, 2016 at 1:18

1 Answer 1

1

First I would structure your data differently to be an array of objects and not an array of arrays. Make sure this is globally accessible.

var data = [
    {
     "street": "",
     "zipcode": 0,
     "city": ""
    }, 
    {
     "street": "",
     "zipcode": 0,
     "city": ""
    },
 ...];

Then change your function accordingly:

function writeNewData() {

    for (i = 0; i < data.length; i++) {
        var address = "";
        // note: loop 5 times because I want to add 2 new values to each array

        // this gives me the full address as a string
        address += data[i].street + " " + data[i].zipcode + " " + data[i].city;

        // add the new data to the array
        getLatLng(address, i);
    }
};

function getLatLng(myAddress, i) {
    GMaps.geocode({
        address: myAddress,
        callback: function(results, status) {
            if (status == 'OK') {
                data[i].lat = results[0].geometry.location.lat();
                data[i].lng = results[0].geometry.location.lng();
            }
        }
    });
}

I pass in i to geoLatLng because that is the current index that the loop had iterated on. Then you are able to use that same i, once the API has returned the lat and lng, to reference back to the correct index inside data.

After waiting for the asynchronous call your object would now look like so:

var data = [
{
 "street": "",
 "zipcode": 0,
 "city": "",
 "lat": 0,
 "lng" : 0
}, 
{
 "street": "",
 "zipcode": 0,
 "city": "",
 "lat": 0,
 "lng" : 0
},

...];

As you can see it is a good bit shorter and more concise. If you need anything cleared up just ask, here are some references on objects and object notation.

W3 Javascript Objects

W3 JSON

Sign up to request clarification or add additional context in comments.

8 Comments

I agree with your comments about the data structure, and this is a clever way to accommodate the user's async issue. But I will say, while this fixes the problem on this code sample, that user is doomed to repeat the async error over and over again. i.e. you should probably describe why the i in getLatLng(myAddress,i) is so important, and how that works.
Thank you sir, good comment, I have added a small description.
This is a really good solution haven't thought of it! One thing I needed to do first though was adding the two new properties to my object with empty values so it wouldn't be undefined later.
Maybe one more thing: I got the object with the lat and lng values now. When I display them in the console I see the correct values for lat and lng but when I create a .csv file from the new object I get 0,0 for lat and lng which is strange because in the console I see the correct values. Any Ideas?
You are right thank you! I opened a seperate topic for that issue :)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.