Storing value in javascript vars - javascript

This might be a lame question, but for me as a javascript newbie it's really a mystery.
Here is a short sample of my code that handles geolocation:
if (navigator.geolocation)
{
var latitude, longitude;
navigator.geolocation.getCurrentPosition(
function(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
// Here I get user's coordinates
alert("Latitude : " + latitude + " Longitude : " + longitude);
},
function() {
alert("Geo Location not supported");
}
);
// Here I don't get anything
alert("Latitude : " + latitude + " Longitude : " + longitude);
new google.maps.Geocoder().geocode({
location: new google.maps.LatLng(latitude ,longitude)
}, this.getCallback());
}
else {
error("Geolocation is not supported by this browser.");
}
As I've already mentioned in the comments - I the first case, I get coordinates, but in the second one, the values of those vars are undefined and thus I can't get the location on the map... What may cause this and how to pass those values to the Geocoder ?

That is how asynchronous requests work. You have to wait till the request completes and then execute the next block of code as callback to the success function. Executing it all in line will cause problems as you are experiencing.
function(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
// Here I get user's coordinates
alert("Latitude : " + latitude + " Longitude : " + longitude);
new google.maps.Geocoder().geocode({
location: new google.maps.LatLng(latitude ,longitude)
}, this.getCallback());
}
note: you'll probably need to change the context of this, for this.callback

Related

How to access google maps API response data

First time trying to hack together some Javascript here so any resources that will help me understand my problem case is appreciated.
I'm trying to extract the lat and long from the following request to use in another request:
var placeSearch, autocomplete;
var x = document.getElementById("location");
function initAutocomplete() {
// Create the autocomplete object, restricting the search predictions to
// geographical location types.
autocomplete = new google.maps.places.Autocomplete(
document.getElementById('autocomplete'), { types: ['geocode'] });
// Avoid paying for data that you don't need by restricting the set of
// place fields that are returned to just the address components.
autocomplete.setFields(['geometry']);
}
function showPosition() {
x.innerHTML = "Latitude: " + autocomplete.result.geometry.lat +
"<br>Longitude: " + autocomplete.result.geometry.lng;
}
/*
"result" : {
"geometry" : {
"location" : {
"lat" : 51.46588129999999,
"lng" : -0.1413263
}
}
*/
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle(
{ center: geolocation, radius: position.coords.accuracy });
autocomplete.setBounds(circle.getBounds());
});
}
}
When a user selects the autocompleted location the google api makes a request to:
https://maps.googleapis.com/maps/api/place/js/PlaceService.GetPlaceDetails on the selected location. I can see this returns my desired data here:
Obviously autocomplete.result.geometry.lat returns a location_search.js:18 Uncaught TypeError: Cannot read property 'geometry' of undefined error so I'm missing some knowledge here.
Thank you for your help.
I've implemented something very similar to your needs in my project recently. It's quite easy but it took me a while to realise how to do it.
Basically, you can simply use the .getPlace() method on the Autocomplete object and go from there. Here's how I got the latitude and longitude:
let locationInfo = autocomplete.getPlace().geometry.location;
let latitude = locationInfo.lat();
let longitude = locationInfo.lng();
In your specific case you should change your showPositions function to
function showPosition() {
x.innerHTML = "Latitude: " + autocomplete.getPlace().geometry.location.lat +
"<br>Longitude: " + autocomplete.getPlace().geometry.location.lng;
}
Does this do the trick?

JavaScript code seems to skip callback to another function

I am writing functions in my JavaScript file to output an address. It is not the cleanest, but it worked before my current issue came up. I am trying to callback and get an address but when I log the address to the console, it is undefined. I'm not sure what I am doing wrong.
function calculateDistance(vnames, vlocations) {
// PROGRAM NEVER GOES THROUGH THIS???
clientLoc((address) => {
var origin = address;
alert("Address: " + address);
});
// PROGRAM NEVER GOES THROUGH THIS???
console.log("my location is: " + origin);
var venueNames = vnames,
venueLocs = vlocations,
service = new google.maps.DistanceMatrixService();
// 5. Output band name and distance
// Matrix settings
service.getDistanceMatrix(
{
origins: [origin],
destinations: venueLocs,
travelMode: google.maps.TravelMode.DRIVING, // Calculating driving distance
unitSystem: google.maps.UnitSystem.IMPERIAL, // Calculate distance in mi, not km
avoidHighways: false,
avoidTolls: false
},
callback
);
// Place the values into the appropriate id tags
function callback(response, status) {
// console.log(response.rows[0].elements)
// dist2 = document.getElementById("distance-result-2"),
// dist3 = document.getElementById("distance-result-3");
for(var i = 1; i < response.rows[0].elements.length + 1; i++) {
var name = document.getElementById("venue-result-" + i.toString()),
dist = document.getElementById("distance-result-" + i.toString());
// In the case of a success, assign new values to each id
if(status=="OK") {
// dist1.value = response.rows[0].elements[0].distance.text;
name.innerHTML = venueNames[i-1];
dist.innerHTML = response.rows[0].elements[i-1].distance.text;
} else {
alert("Error: " + status);
}
}
}
}
This is the function I am using the callback from:
// Find the location of the client
function clientLoc (callback) {
// Initialize variables
var lat, lng, location
// Check for Geolocation support
if (navigator.geolocation) {
console.log('Geolocation is supported!');
// Use geolocation to find the current location of the client
navigator.geolocation.getCurrentPosition(function(position) {
console.log(position);
lat = position.coords.latitude;
lng = position.coords.longitude;
// Client location coordinates (latitude and then longitude)
location = position.coords.latitude + ', ' + position.coords.longitude
// console.log(location)
// Use Axios to find the address of the coordinates
axios.get('https://maps.googleapis.com/maps/api/geocode/json?key=AIzaSyAg3DjzKVlvSvdrpm1_SU0c4c4R017OIOg', {
params: {
address: location,
key: 'AIzaSyBH6yQDUxoNA3eV81mTYREQkxPIWeZ83_w'
}
})
.then(function(response) {
// Log full response
console.log(response);
var address = response.data.results[0].formatted_address;
// Return the address
console.log(address);
//return clientLoc.address;
// CALLBACK
callback(address);
})
});
}
else {
console.log('Geolocation is not supported for this Browser/OS version yet.');
return null;
}
}
a function that has a callback doesn't block execution, so your function clientLoc gets called and presumably if that code works, the origin variable will get set and your alert call will fire ... BUT the code below clientLoc is not waiting for the clientLoc call to finish ... it proceeds through the rest of the function ... granted i'm not too familiar with the es6 syntax but the concept is the same. You probably want to move the console.log("my location is: " + origin); and any code that reiles on the origin variable being set inside the callback, to make it cleaner use some promises

Geolocation - Assign the latitude and longitude values to variables [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 6 years ago.
I followed the examples on how to get current position (longitude and latitude) in javascript and have tried it and works fine.
My issue is with assigning the lng and lat values to variables so that i can always reuse them. I understand the function is some sort of async call.
From the example below, within the showPosition function my current location is printed (fine as expected!) but out the function prints undefined.
What is the best way to get the lat ang lng values so that they can be used in other functions.
var lat;
var lng;
// users current location using HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
function showPosition(position) {
lat = position.coords.latitude;
lng = position.coords.longitude;
console.log("lat: " + lat + "lng: " + latlng); // works fine prints current position
}
console.log("lat: " + lat + "lng: " + latlng); // prints undefined
Seems a scope issue .. try declaring the vars outside the function
var lat;
var lng;
// users current location using HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
function showPosition(position) {
lat = position.coords.latitude;
lng = position.coords.longitude;
console.log("lat: " + lat + "lng: " + latlng); // works fine prints current position
}
console.log("lat: " + lat + "lng: " + latlng); // prints undefined

Javascript change value of global variable

var longitude=1;
var latitude=1;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': Position}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
alert(results[0].geometry.location.lat());
alert(results[0].geometry.location.lng());
latitude = results[0].geometry.location.lat();
longitude = results[0].geometry.location.lng();
//alert("location : " + results[0].geometry.location.lat() + " " +results[0].geometry.location.lng());
} else {
alert("Something got wrong " + status);
}
});
I am trying to change the values of global variables latitude and longitude but not able to. I have looked up the way to assign values to global variables inside a function and I think I am doing that part right. But clearly there is something that I am missing. Please help.
The function(results, status){ ... } bit is an asynchronous callback
The issue you're likely running into is that you're trying to access the longitude and latitude values before they're actually set
To confirm this, modify your callback to the following
// where you have these two lines
latitude = results[0].geometry.location.lat();
longitude = results[0].geometry.location.lng();
// add this line after
console.log(latitude, longitude);
You should see them just fine. Once you have that bit working, you could skip them altogether and do something like this
function doSomething(lat, lng) {
console.log(lat, lng);
}
geocoder.geocode( { 'address': Position}, function(results, status) {
// ...
var loc = results[0].geometry.location,
lat = loc.lat(),
lng = loc.lng();
doSomething(lat, lng);
// ...
});
This way you can skip having latitude and longitude in the outer scope, too. Pretty handy!
I recommend you attach those two variable to the global window object.
Like: window. latitude and window.longitude
And the function trying to change the value is an async callback function, there might be local variable with the same name defined in that scope.
Attaching it to window should get you around that possibility.
Try this code:
var longitude=1;
var latitude=1;
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': Position}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
latitude = results[0].geometry.location.lat();
longitude = results[0].geometry.location.lng();
alert(latitude + ', ' + longitude) // show the value of the globals
} else {
alert("Something got wrong " + status);
}
});
If that works correctly, then the answer is probably that the globals are being correctly set, but they simply haven't been set by the time other code attempts to use them.
If this occurs, it means that whatever code relies on the lat/long needs to wait until the geocode callback has finished and received data.

google maps geocoding and order of initialization

so I've run into a problem recently, and maybe you guys can help.
So to start off, I've created website and a marker, and I'm trying to retrieve the center point to reverse-geocode the address.
My code is below :
function ReverseGeocode(lat, lng)
{
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"latLng": latlng}, function(results, status)
{
if (status != google.maps.GeocoderStatus.OK)
{
alert("Geocoding has failed due to "+ status);
}
address = results[0].formatted_address;
});
}
The problem I'm having here, is when I try to pass "address" back out (address is right now a global variable) all I get is "undefined".
Here's the code where I'm trying to pass it back out:
sendString += '&lat=' + lat;
sendString += '&lng=' + lon;
ReverseGeocode(center.lat(), center.lng());
alert(""+address);
sendString += '&address=' + address
var currentLang = "en"
sendString += '&phone=' + document.getElementById("number").value;
sendString += '&email=' + document.getElementById("email").value;
sendString += ($("prefsms").checked)?'&contactMethod=sms':'&contactMethod=email';
sendString += '&serviceType=' + document.getElementById("serviceType").value;
sendString += '&language=' + currentLang;
alert(""+sendString);
In my alert box, all I get is "undefined". Yet, if I add another alert box INTO the ReverseGeocode function, I'll get the address in an alert box, but this occurs AFTER the alert box in the outside function.
Any ideas as to what's going on? I would have thought that the alert box inside the ReverseGeocode function would go first, not the other way around.
Thanks!
As Heitor Chang said, Geocoding is asynchronous - so when you try to return the address, it get's returned to the function you pass as a callback to geocoder.geocode(). Confused? see this:
function ReverseGeocode(lat, lng)
{
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"latLng": latlng}, function(results, status)
{
if (status != google.maps.GeocoderStatus.OK)
{
alert("Geocoding has failed due to "+ status);
}
return results[0].formatted_address; // this is how you might've been returning (i am just assuming since you didn't provide any code that returns address.
});
}
Now you can see that it gets returned to the function you are passing to geocoder.geocode()
What you should be doing is use callbacks - you are passing one here, probably without realising it - accept a callback as the third argument to ReverseGeocode function and when you get the result as OK, call the callback and return the address. Here's how:
function ReverseGeocode(lat, lng, cb) // cb - callback, a function that takes the address as an argument.
{
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({"latLng": latlng}, function(results, status)
{
if (status != google.maps.GeocoderStatus.OK)
{
alert("Geocoding has failed due to "+ status);
}
cb(results[0].formatted_address); // call the callback passing to it the address and we're done.
});
}
How to use it? This way:
ReverseGeocode( LAT, LNG, function(address) {
// do something with the address here. This will be called as soon as google returns the address.
});
(Reverse) Geocoding is asynchronous, meaning the request goes to Google servers, your script keeps running, and the code inside result is OK block executes when Google sends back its reply. The overall execution won't necessarily follow the order of commands in the order it was written.
To use the value of address your code has to be included in that code block where the status returned is OK.

Categories