简体   繁体   中英

Why is function returning undefined

Can someone help me understand why the following alerts undefined, I have a feeling its something to with needing a callback but I am unsure. basically All I want to do is return this function and then add it to an html element.

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition);
    } else {
        alert("Geolocation is not supported by this browser.");
    }
}

function showPosition(position) {

    var lat = position.coords.latitude;
    var lon = position.coords.longitude;

    var lat1 = <?php echo the_sub_field('google_maps_lat'); ?>;
    var lon1 = <?php echo the_sub_field('google_maps_long'); ?>;

    var R = 6371; // Radius of the earth in km
    var dLat = deg2rad(lat1-lat);  // deg2rad below
    var dLon = deg2rad(lon1-lon); 
    var a = 
        Math.sin(dLat/2) * Math.sin(dLat/2) +
        Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat)) * 
        Math.sin(dLon/2) * Math.sin(dLon/2); 

    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
    var d = R * c; // Distance in km

    //if i alert here it would show the correct results
    return d                            
}

function deg2rad(deg) {
    return deg * (Math.PI/180)
}

//This returns undefined
alert(getLocation());

getLocation() can't return a value because navigator.geolocation.getCurrentPosition is an asynchronous function that expect callbacks to run on success and error.

So even if you'll have a return statement it will always return undefined because it's work we'll only be done after return was invoked.

To solve that you should use promises. The example below works with native javascript promises , which are not supported in IE. If you need IE support, use a promises library, such as bluebird .

function getLocation() {
    return new Promise(function(resolve, reject) { // create a new promise
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) { // send the callback to getCurrentPosition()
                resolve(showPosition(position)); // when the callback is invoked resolve using the result of showPosition()
            }, function(PositionError) { // error callback
                reject(PositionError); // reject using the PositionError from the callback
            });
        } else {
            alert("Geolocation is not supported by this browser.");
            reject('not supported'); // if not supported reject
        }
    });
}

getLocation().then(function(result) { // use the promise then to get the result and display it in the alert
    alert(result);
});
 var options = {
 enableHighAccuracy: true,
 timeout: 5000,
 maximumAge: 0
 };

function getLocation() {
   if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(showPosition, error, options);
   } else {
      alert("Geolocation is not supported by this browser.");
   }

return 'whatever you want to return when it fails';
}

function error(err) {
   console.warn('ERROR(' + err.code + '): ' + err.message);
};


function showPosition(position) {
  var lat = position.coords.latitude;
  var lon = position.coords.longitude;

  var lat1 = <?php echo the_sub_field('google_maps_lat'); ?>;
  var lon1 = <?php echo the_sub_field('google_maps_long'); ?>;

  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat1-lat);  // deg2rad below
  var dLon = deg2rad(lon1-lon); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2); 

  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km

  //do whatever with d
  callSomeOtherFunction(d)                            
}

As @Pointy mentioned, you can't return values through an asynchronous API.

Try using a global variable.

    var desiredValue;

    function showPosition(position) {
        /*
             Rest of the function
        */
        desiredValue = d;  
    }

    function getLocation() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(showPosition);
        } else {
            alert("Geolocation is not supported by this browser.");
        }
    }

    getLocation();
    alert(desiredValue);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM