4
votes

Been trying for 1.5 hours. Can someone please help me out? "your post appears to contain code that is not properly formatted as code" issue. Please can someone help me format this code? It works now in this post, but not when making a new one... Now I cannot make a new post for a day... What the...

FIXED: It appears that the browser output had to be in code layout.

This was my original question:

TITLE: Working with geolocation API - scope question

Hi all

I am working with Mapbox and am trying to update the vars lngreal and latreal (from default Greenwhich coordinates). The function initializeMap() is called during setup, and the idea is that it updates it with user's longlat coordinates if possible. When I run the code below...

function initializeMap() {

    mapboxgl.accessToken = 'HIDDEN FOR THIS POST';

    var lngreal = 0.0098;
    var latreal = 51.4934;

    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(displayLocationInfo);

    }

    function displayLocationInfo(position) {
        //Why does this not work to update the map zoom?

        lngreal = position.coords.longitude;
        latreal = position.coords.latitude;
        console.log(lngreal);
        console.log(latreal);
    }

    console.log(lngreal);
    console.log(latreal);



    // This adds the map to your page

    var map = new mapboxgl.Map({
        // container id specified in the HTML

        container: 'map',
        // style URL

        style: 'mapbox://styles/mapbox/light-v10',
        // initial position in [lon, lat] format

        center: [lngreal, latreal],
        // initial zoom

        zoom: 14
    });

   // More code after this but not related

}

It shows the following in html inspector console:

play-mapboxscripts.js:21 0.0098  
play-mapboxscripts.js:22 51.4934  
play-mapboxscripts.js:17 4.9212796  
play-mapboxscripts.js:18 52.333704999999995  
  1. Why does it first show the last console.log lines, instead of the console.log lines in the displayLocationInfo function? Isn't that function called in the navigator.geolocation function, which comes before that?

  2. I cannot get the lngreal and latreal variables updated correctly to match the user's location. They will default back to 0.0098 and 51.4934, and the loaded map (var map) will show the default Greenwhich location. Does this have to do with variable scope of the displayLocationInfo function?

2
I'm voting to close this question as off-topic because this seems to be an issue with SO itself, so should go to meta.stackoverflow.com - Daniel Hilgarth
I added some example code, hope it helps. - Chris G
wrap code in ``` - Dmitry Reutov
No, don't. Use indentation instead. Mark it and press Ctrl+K - Chris G
Don't make a new question. Edit this one. Include how the code fails, what errors you're getting, and what the exact issue is. - Chris G

2 Answers

1
votes

It shows the last two console logs first because displayLocationInfo is the callback to the async method getCurrentPosition and so has to wait until that process has resolved before it can log the new coords.

To recenter the map with the new coords you need to do something like this:

function displayLocationInfo(position) {
  const { coords: { latitude, longitude } } = position;

  // Get a new lat/lng object
  // https://docs.mapbox.com/mapbox-gl-js/api/#lnglatlike
  const center = new mapboxgl.LngLat(longitude, latitude);

  // Center the map
  // https://docs.mapbox.com/mapbox-gl-js/api/#map#setcenter
  map.setCenter(center);
}
0
votes

Thanks Andy and @Chris G. I wasn't aware of asynchronous functions and am happy to have read about them now. Very helpful.

I have a question about callbacks, which relates to this topic. How does a function know that something is a callback; something that needs to be executed once certain I/O has completed. How does it know that it shouldn't execute right away? Is it defined in a function in a (standardized) way?

As far as I know the 'callback' keyword that is often used in an argument is just common practise, but does not automatically let the function interpret the argument as something that should start once certain I/O has completed.

Taking the below example, I have three questions (taken from https://medium.com/codebuddies/getting-to-know-asynchronous-javascript-callbacks-promises-and-async-await-17e0673281ee):

const request = require(‘request’);
function handleResponse(error, response, body){
    if(error){
        // Handle error.
    }
    else {
        // Successful, do something with the result.
    }
}
request('https://www.somepage.com', handleResponse);
  1. What does the structure of the 'require' function look like so that it knows that argument 2 (handleResponse in this case) should be executed once the request has completed? I guess this gets down to the same question that I asked above.

  2. Can functions be asynchronous even without the async keyword in the function? If yes, how does the browser know it's an asynchronous function?

  3. In my code, is it possible to have the browser/script wait with execution of remaining code until the navigator.geolocation.getCurrentPosition has finished executing and therefore updated the lngreal latreal coords?