2

Tried to push two values to an array to later use the values for db integration. Adding the values to the array is going smoothly, however when fetching the values it returns undefined.

var array = [];

var lat = 54.333;
var lng = 12.556;

array.push(lat, lng);

console.log(array[0]); // Returns undefined

The array looks like this in the console if i just use console.log(array);

Array[0]
- 0: Object
-- 0: 54.333
-- 1: 12.556

Have i missed some sort of hierarchy when trying to display the array?

EDIT: Here is a code-snippet for what exactly dosen't work for me.

var address = 'Champ de Mars, 5 Avenue Anatole France, 75007 Paris,    Frankrike';

var array = [];

$.get('https://maps.googleapis.com/maps/api/geocode/json?address=' +      encodeURIComponent(address), function(data, status) {
      var lat = data.results[0].geometry.location.lat;
      var lng = data.results[0].geometry.location.lng;

      array.push({lat, lng});
  });

console.log(array)

if (array[0] === undefined) {
    console.log('this sucks');
} else {
    console.log('it works');
}
4
  • Your code looks fine.. Note that console.log returns undefined, but it should print out array[0] value. Commented Feb 11, 2017 at 3:36
  • array[0] is 54.333 like you expect. Are you trying to log this from the console directly? If so, you only need to type array[0] to see its value. Commented Feb 11, 2017 at 3:36
  • I do not get undefined from your code. jsfiddle.net/f1ym9kwc Commented Feb 11, 2017 at 3:36
  • 1
    @choz Hmm, wierd. I uploaded a more concrete example on jsfiddle.. jsfiddle.net/f1ym9kwc/1 Commented Feb 11, 2017 at 3:52

3 Answers 3

3

As of your sample in fiddle, It's normal that your array in console is still empty because you're using $.get which does an asynchronous process (AJAX).

In short, you're logging the output before the operation of $.get finishes.

When it finishes, you should see your array has the lat and lng value.

You'll notice the output in console would be like,

var address = 'Champ de Mars, 5 Avenue Anatole France, 75007 Paris, Frankrike';
var array = [];

$.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURIComponent(address), function(data, status) {
    var lat = data.results[0].geometry.location.lat;
    var lng = data.results[0].geometry.location.lng;

    /* Array got pushed here */
    array.push({
        lat,
        lng
    });

    /* This console is executed 3rd */
    console.log("Array just got pushed with lat n lng :::", array);
});

/* This console is executed 1st */
console.log("Printing value of array 1 :::", array)


/* These consoles are executed 2nd */
if (array[0] === undefined) {
    console.log('this sucks');
} else {
    console.log('it works');
}

This is the result of your console.log

> Printing value of array 1 ::: []
> this sucks
> Array just got pushed with lat n lng ::: [Object]

Here's your updated fiddle

Edit:

As per your comment, one way to achieve what you want could be something like this.

var getAddressLatLng = function (address) {
    var defer = $.Deferred();

    $.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURIComponent(address), function (data) {
        if (data && data.results && data.results.length) {
            var res = data.results[0];

            if (typeof(res) === "object" && res.hasOwnProperty("geometry") && res.geometry.hasOwnProperty("location") && typeof(res.geometry.location) === "object") {
                var lat = res.geometry.location.lat,
                    lng = res.geometry.location.lng;

                if (lat && lng) {
                    defer.resolve({
                        "latitude": lat,
                        "longitude": lng
                    });
                }
            }
        }

        defer.resolve(null);
    });

    return defer;
};

Or if you dont want to use $.gets callback function, You can do;

var getAddressLatLng = function (address) {
    return $.get('https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURIComponent(address)).then(function (data) {
        if (data && data.results && data.results.length) {
            var res = data.results[0];

            if (typeof(res) === "object" && res.hasOwnProperty("geometry") && res.geometry.hasOwnProperty("location") && typeof(res.geometry.location) === "object") {
                var lat = res.geometry.location.lat,
                    lng = res.geometry.location.lng;

                if (lat && lng) {
                    return {
                        "latitude": lat,
                        "longitude": lng
                    };
                }
            }
        }

        return null;
    });
}; 

To use it, you can just call the function like;

getAddressLatLng("Champ de Mars, 5 Avenue Anatole France, 75007 Paris, Frankrike").then(function (result) {
    /* result is either 'null' or an object with 'lat' and 'lng' property */
    if (result) {
        console.log("RESULT:: ", result);
        /* And you can do your db operation here */
    }

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

5 Comments

I think i get it now. Super much thanks! Is there any easier way to do this procedure, say if i want to add this information to a database? If not, is there anyway to control when the loading of the API is done?
@h.johan You can do that by executing your code right after the array gets pushed which is inside the $.get callback function (It's where I put the 3rd console)
Can i add some kind of return; so i don't add a empty field when integrating with the database later on?
.get already returns a promise, why do you need to return another promise and and resolve that promise when the .get promise is resolved? You could just return the result of .get.
@TinyGiant I wasn't returning $.get, but executing the result inside its callback function. However, I edited my answer to what you might expect it to be
3

console.log shows objects as they are when they are expanded, not how they are when logged.

Because the jQuery get call is asynchronous, at the time array is logged, it is an empty array; but by the time you expand it in the console, the AJAX call has completed and the array is filled. At the time array[0] is logged, array is still an empty array so there is no index at index 0, thus undefined is returned.

You can use console.dir to log the object as it is at the time it is logged:

$.get(url, function(data, status) {
  var lat = data.results[0].geometry.location.lat;
  var lng = data.results[0].geometry.location.lng;
  array.push({ lat, lng });
});

console.dir(array);

var address = 'Champ de Mars, 5 Avenue Anatole France, 75007 Paris, Frankrike';
var array = [];
var url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURIComponent(address);

$.get(url, function(data, status) {
  var lat = data.results[0].geometry.location.lat;
  var lng = data.results[0].geometry.location.lng;
  array.push({ lat, lng });
});

console.dir(array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

If you want to run the code after the callback has completed, you can use a .then call:

$.get(url, function(data, status) {
  var lat = data.results[0].geometry.location.lat;
  var lng = data.results[0].geometry.location.lng;
  array.push({ lat, lng });
}).then(function() {
  console.dir(array);

  if (array[0] === undefined) {
    console.log('this sucks');
  } else {
    console.log('it works');
  }
});

var address = 'Champ de Mars, 5 Avenue Anatole France, 75007 Paris, Frankrike';
var array = [];
var url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURIComponent(address);

$.get(url, function(data, status) {
  var lat = data.results[0].geometry.location.lat;
  var lng = data.results[0].geometry.location.lng;
  array.push({ lat, lng });
}).then(function() {
  console.dir(array);
  
  if (array[0] === undefined) {
    console.log('this sucks');
  } else {
    console.log('it works');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

If you're looking up the coordinates for multiple addresses, you can push the get calls into an array, and use jQuery's $.when. This will only execute once all of the lookups have finished.

var addresses = ['Champ de Mars, 5 Avenue Anatole France, 75007 Paris, Frankrike',
                 'Carrousel de la tour Eiffel, Prom. Quai Branly, 75007 Paris, France'];
var array = [];
var promises = addresses.map(function(address) {
  var url = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + encodeURIComponent(address);
  return $.get(url, function(data, status) {
    var lat = data.results[0].geometry.location.lat;
    var lng = data.results[0].geometry.location.lng;
    array.push({ lat, lng });
  });
});

$.when.apply($, promises).then(function() {
  console.dir(array);
  
  if (array[0] === undefined) {
    console.log('this sucks');
  } else {
    console.log('it works');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

2 Comments

Ok, many thanks! So, the function you added in the last example .then holds the script until $.get is done?
Yes, it's a promise
1

You're seeing undefined because that is the return value of console.log. That is, console.log doesn't have a return value, and so you see undefined in your console.

Comments

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.