Mohamad
Mohamad

Reputation: 37

Variable value is undefined in Javascript

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

Answers (2)

3limin4t0r
3limin4t0r

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

Sushmit Sagar
Sushmit Sagar

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

Related Questions