1

I thought I understood how the default operand worked in JavaScript, but clearly not. I'm trying to first determine the user's geographic position, and load a map centered on those coordinates. If the device is unable to determine those coordinates, it would fallback to just loading the map with some default values.

You'll notice that in my error method, I'm calling gMap.init() with no arguments, which I thought should mean that the variables lat and lon should be set to 57.700992 and 11.893836 respectively. Instead, I'm getting Uncaught TypeError: Cannot read property 'coords' of undefined. Where am I going wrong?

Also, in theApp.init() I'm calling the map if navigator.geolocation exists. Does that mean browsers that don't support HTML5 geolocation will not even try loading the map?

var gMap = {
    init: function (position) {

            var lat = position.coords.latitude || 57.700992,
                lon = position.coords.longitude || 11.893836,
                geocoder =  new google.maps.Geocoder(),
                mapOptions = {
                    zoom: 12,
                    center: new google.maps.LatLng(lat, lon)
                },
                map = new google.maps.Map(document.getElementById('mapcanvas'), mapOptions);

    },
    error: function () {
        console.log('failed to retrieve geoposition');
        gMap.init();
    }
}


var theApp = {
    init: function () {

        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(gMap.init, gMap.error, {timeout:10000});
        }

    }
}
Jezen Thomas
  • 13,619
  • 6
  • 53
  • 91
  • 1
    Assuming you're talking about `||`, it's not the "default operand", it's the "logical OR operator". The error you're getting is nothing to do with that operator, it is because `position` is `undefined` so `position.coords` is an error. Try `lat = position && position.coords.latitude || 57.700992` – nnnnnn Nov 30 '12 at 10:26
  • `position.coords` position is undefined, you can't access a property of an undefined variable. – Fabrício Matté Nov 30 '12 at 10:27
  • Sorry, it _is indeed_ called the default operand. Check [here](http://stackoverflow.com/questions/1378619/javascript-operator) and [here](http://javascript.crockford.com/survey.html). – Jezen Thomas Nov 30 '12 at 10:28
  • Defaulting operator is an alias for the OR operator in JavaScript due to its peculiar behaviour. – Fabrício Matté Nov 30 '12 at 10:29
  • 1
    It's not an "operand" at all, it's an "operator". The operands are the expressions it operates on, in your case `position.coords.latitude` and `57.700992`. It's _normally_ called "logical OR" operator because in most languages and in JS with boolean operands that's what it does, though JavaScript has a kind of special implementation of logical OR that allows it to be used on non-booleans which is why you can use it to help set default values in certain cases. – nnnnnn Nov 30 '12 at 10:32
  • although I'm not really into it, coffee script would make this task easier : `position?.coords?.latitude || 'default' ` – gion_13 Nov 30 '12 at 10:33
  • Alright. Whatever. @nnnnnn if you submit an answer containing `lat = position && position.coords.latitude || 57.700992`, I'll mark it as correct. It looks pretty elegant to me, and I've learned from it. – Jezen Thomas Nov 30 '12 at 10:34
  • Cerbrus's answer covers the same ground and more, no need for me to duplicate. – nnnnnn Nov 30 '12 at 10:36

2 Answers2

1

The || you have there should work, unless position.coords or position is undefined. In that case, JavaScript will throw a error because you're trying to access a property on a undefined object.
You will have to manually check if the objects exist:

var lat, lon;
if(position && position.coords){
    lat = position.coords.latitude || 57.700992;
    lon = position.coords.longitude || 11.893836;
}

If position is undefined, the if will abort, without trying to check for position.coords.
(The && doesn't evaluate the right parameter, if the left one is false)

And yes, if navigator.geolocation is undefined, the map will not be loaded:

navigator.geolocation.getCurrentPosition(gMap.init, gMap.error, {timeout:10000});

This ^ will not be executed, so gMap.init will not be executed.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • I wrote it like this instead: `lat = position && position.coords.latitude || 57.700992`, but great answer nonetheless. Thanks! – Jezen Thomas Nov 30 '12 at 10:39
  • I prefer using the `if` here, because you're only evaluating `position` / `position.coords` once. But both work, and yours is more compact. Thanks! – Cerbrus Nov 30 '12 at 10:42
-1

You should try

 var lat = position.coords.latitude ? window['position'] != undefined : 57.700992,
 lon = position.coords.longitude ? window['position'] != undefined : 11.893836,

instead of ||

Jacob George
  • 2,559
  • 1
  • 16
  • 28