JSON APIs and AJAX - Get Geolocation Data to Find A User's GPS Coordinates

i can get the code to pass the test, maybe i’m getting a bit sidetracked, but…
no matter what i try i can’t get the getCurrentPosition function to set or return a variable (global or otherwise).
the code seems to run the function last and logs whilst the lat variable is undefined.
feel like i’m missing something fundamental.

Your code so far

<script>
  // Add your code below this line
const successCallback = (position) => {
  lat = position.coords.latitude
  console.log('success callbak pos:', position.coords.latitude, position.coords.longitude)
};
const latCallback = (position) => {
  return position.coords.latitude
}
const errorCallback = (error) => {
  console.log(error);
};
var lat
var lon

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      lat = position.coords.latitude
      document.getElementById('data').innerHTML="latitude: " + position.coords.latitude + "<br>longitude: " + position.coords.longitude;
    })
  }
lat = navigator.geolocation.getCurrentPosition(latCallback)
console.log('outdoorz:', lat, navigator.geolocation.getCurrentPosition(successCallback))

  // Add your code above this line
</script>
<h4>You are here:</h4>
<div id="data">

</div>

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36

Challenge: JSON APIs and AJAX - Get Geolocation Data to Find A User’s GPS Coordinates

Link to the challenge:

When you copy that if statement into the code, do you get an alert asking you for access to your location? Because I did. And when I clicked yes, the latitude and longitude showed up.

Right, that is normal behavior.

Getting the lon/lat is asynchronous, meaning that it is not instantaneous and JS will not wait. It may be microseconds, it may be years, but JS will not wait. So, JS dispatches that asynchronous action and continues on and does the log statement at the bottom. Then, at some point in the future (maybe microseconds) the geo info returns and the callback gets run.

That’s why we use callbacks, “Hey, when you get back with the information, call this function.” Later on you can graduate to Promises and async/await.

It is important to learn - a lot of what we do with JS is async. But yeah, it is very confusing at first - you’re in good company. I’d hit up a bunch of blog articles and youtube videos. It will take a while, but you’ll get there.

1 Like

yes, i just am struggling to set variables to navigator.geolocation data

but i wudda thought i could set variables in the callback function therefore?

Do you want to be able to use the variables from outside the function? I only know it’ll work if you set the variables from inside the function itself like this

let lat 

if (navigator.geolocation){
  navigator.geolocation.getCurrentPosition(function(position) {

    lat = position.coords.latitude
    document.getElementById('data').innerHTML="latitude: " + lat + "<br>longitude: " + position.coords.longitude;
  });
}

to Bl1xvan:
no, i dont think that works for the reason kevin gave. but i tried to do it in the callback. same story.
i suppose the logs run before the callback executes. so it would be

yep…

lat = navigator.geolocation.getCurrentPosition(latCallback)
console.log('outdoorz:', lat)
setTimeout(() => {
  console.log("Delayed for 1 second.outdoorz:", lat);
}, "1000")

just a timeout on the log and it works. few! it can set variables but beware

but i wudda thought i could set variables in the callback function therefore?

Right, but your log statement will get called before they get set.

1 Like

was just wondering where the succesCallback would come in in this code, would it look like this:

<script>
  // Add your code below this line
const successCallback = (position) => {
  console.log('success')
};
const errorCallback = (error) => {
  console.log(error);
};
let lat, lon = 0

  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      lat = position.coords.latitude
      lon = position.coords.longitude
      document.getElementById('data').innerHTML="latitude: " + position.coords.latitude + "<br>longitude: " + position.coords.longitude;
      successCallback()
    })
  }
//navigator.geolocation.getCurrentPosition(successCallback)
setTimeout(() => {
  console.log(lat,lon);
}, "1000")
  // Add your code above this line
</script>
<h4>You are here:</h4>
<div id="data">

</div>

(the setTimeout can be ignored, thats just my debug)

or do i put the other stuff in the successCallback function with the if statement?
(sorry, i think i’ve jumped ahead in the course and i need to step back)

The success callback is what you pass to the _ getCurrentPosition_ method. So I would either expect to this:

navigator.geolocation.getCurrentPosition(function(position) {
  // do my success stuff here, this is my success callback
})

Here we have passed an anonymous function to getCurrentPosition, who will use it as the success callback.

But we could also create a named function to pass:

function mySuccessHandler(position) {
  // do my success stuff here, this is my success callback
}

navigator.geolocation.getCurrentPosition(mySuccessHandler)

They way that you’ve done:

const successCallback = (position) => {
  console.log('success')
};

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(function(position) {
    // do some success related stuff
    successCallback()
  })
}

To me that just looks odd. You are calling a function called “successCallback” from the actual success callback.

1 Like

so would the errorCallback code be built into the if statement in your anonymous example?
whereas a named function could use syntax:
getCurrentPosition(success, error) .
(the named one looks cleaner to me)

Yeah, the named callback is a little cleaner. Sometimes if I just have something short I’ll just stick it in there.

The behavior of the error handler is the same. You can create it anonymously in the in method call or define it elsewhere and pass the reference. It doesn’t really matter where you do it, as long as the reference is in scope.

1 Like

the scope was bothering me a bit. doesn’t seem to matter if i declare lat at all, or whether let or var, but it is passed as parameter within named function.

//let lat
//var lat

const successCallback = (position) => {
      /*var*/ lat = position.coords.latitude
      lon = position.coords.longitude
      document.getElementById('data').innerHTML="latitude: " + position.coords.latitude + "<br>longitude: " + position.coords.longitude;
  console.log('success', lat, lon)
};

const errorCallback = (error) => {
  console.log(error);
};
navigator.geolocation.getCurrentPosition(successCallback, errorCallback) 

setTimeout(function(){
  console.log(lat)
},1000)

(just noticed start a new topic request, i wont expect a reply, i shall figure it out)

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.