Reputation: 37
I am trying to get the user location by using HTML5 geolocation. The lat and lng value are received successfully and I can show it on the map. I want to save the user location to use it later so I defined origin variable and I concatenated the lat and lng variables and then I assigned the concatenated value to origin. When I am trying to use the origin value later its value is undifined. Could someone please tell me when the problem is in the code. I guess the problem is very silly but I cannot solve it. I don't think the problem is related to variable scope.
Here is the code:
let map ;
// initialize the map and show it on the dashboard.
function initMap()
{
// Map options.
let options =
{
center :
{
lat : 41.015137,
lng : 28.979530
},
zoom : 12
}
// New map.
map = new google.maps.Map
(
document.getElementById('map'),
options
);
};
$(document).ready
(
function()
{
$("#order_and_show").click
(
function()
{
// Change the text of the title and the button when get order from the user.
$('#order_title').text('Cancel the order right now') ;
$('#order_and_show').text('Cancel Now') ;
// Get user location from browser using HTML geolocation.
let origin ;
// HTML5 geolocation.
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition
(
function(position)
{
let pos =
{
lat: position.coords.latitude,
lng: position.coords.longitude
} ;
origin = position.coords.latitude + ',' + position.coords.longitude ;
// Add marker.
let marker = new google.maps.Marker
(
{
position : pos,
map : map,
}
) ;
// Center the map according to user location.
map.setCenter(pos);
// Add popup window for user location information
let infoWindow = new google.maps.InfoWindow
(
{
content : '<h6>Your Location</h6>'
}
) ;
marker.addListener
(
'click',
() =>
{
infoWindow.open(map, marker) ;
}
) ;
},
function()
{
handleLocationError(true, infoWindow, map.getCenter());
}
);
}
else
{
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
// Handle Geolocation errors.
function handleLocationError(browserHasGeolocation, infoWindow, pos)
{
infoWindow.setPosition(pos);
infoWindow.setContent
(
browserHasGeolocation ? 'Error: The Geolocation service failed.' : 'Error: Your browser does not support geolocation.'
) ;
infoWindow.open(map);
}
console.log(origin) ;
}
) ;
}
) ;
Upvotes: 0
Views: 106
Reputation: 21150
The problem with your current code is that you try to access origin
outside of the callback that sets it. The getCurrentPosition
callback is probably executed asynchronously, thus when you try to access origin
outside of the callback the callback function is not yet executed resulting in a origin
value of undefined
. You could use promises or async
/await
to solve this issue. Such a solution might look like this:
$(document).ready(function () {
const map = new google.maps.Map(
document.getElementById("map"),
{ center: { lat: 41.015137, lng: 28.979530 }, zoom: 12 }
);
function handleLocationError(infoWindow, msg) {
infoWindow.setPosition(map.getCenter());
infoWindow.setContent(msg);
infoWindow.open(map);
}
$("#order_and_show").click(async function () {
// notice the async keyword ^
$('#order_title').text('Cancel the order right now');
$('#order_and_show').text('Cancel Now');
let position, origin;
if (navigator.geolocation) {
try {
// await the position before continuing
position = await new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject);
});
let pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
origin = position.coords.latitude + ',' + position.coords.longitude;
let marker = new google.maps.Marker({position: pos, map: map});
let infoWindow = new google.maps.InfoWindow({
content: '<h6>Your Location</h6>'
});
map.setCenter(position);
marker.addListener('click', () => infoWindow.open(map, marker));
} catch (error) {
// I'm not sure how you are able to access infoWindow here since it's
// created in the try block after the error is thrown.
handleLocationError(infoWindow, 'Error: The Geolocation service failed.')
}
} else {
// Same here, you don't have access to infoWindow, since it's not created
// yet. However both the above and this are present to mimic the question
// structure.
handleLocationError(infoWindow, 'Error: Your browser does not support geolocation.');
}
// origin should be available unless geolocation isn't supported or
// getCurrentPosisiton failed to execute successfully
console.log(origin);
});
});
For more info about working with asynchronous behaviour I recommend checking out the MDN Using Promises guide.
Upvotes: 1
Reputation: 1508
I am not sure but I think problem seems to be with this line:
let infoWindow = new google.maps.InfoWindow({
content: "<h6>Your Location</h6>"
});
You have declared infoWindow
using let
keyword which is why I think it is scoped within function(position) { .. }
block and which is why infoWindow
is being passed to handleLocationError
function. The same could be said for let pos
variable. declaring your variables globally could solve the problem.
declare pos, marker and infoWindow
varibles in the same line let origin;
like so:
let origin, pos, marker, infoWindow;
Final Code Should look like this, hope it helps:
let map;
// initialize the map and show it on the dashboard.
function initMap() {
// Map options.
let options = {
center: {
lat: 41.015137,
lng: 28.97953
},
zoom: 12
};
// New map.
map = new google.maps.Map(document.getElementById("map"), options);
}
$(document).ready(function() {
$("#order_and_show").click(function() {
// Change the text of the title and the button when get order from the user.
$("#order_title").text("Cancel the order right now");
$("#order_and_show").text("Cancel Now");
// Get user location from browser using HTML geolocation.
let origin, pos, marker, infoWindow;
// HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
origin = position.coords.latitude + position.coords.longitude;
// Add marker.
marker = new google.maps.Marker({
position: pos,
map: map
});
// Center the map according to user location.
map.setCenter(pos);
// Add popup window for user location information
infoWindow = new google.maps.InfoWindow({
content: "<h6>Your Location</h6>"
});
marker.addListener("click", () => {
infoWindow.open(map, marker);
});
},
function() {
handleLocationError(true, infoWindow, map.getCenter());
}
);
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
// Handle Geolocation errors.
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(
browserHasGeolocation
? "Error: The Geolocation service failed."
: "Error: Your browser does not support geolocation."
);
infoWindow.open(map);
}
console.log(origin);
});
});
Upvotes: 0