-1

I am having some issues with my JavaScript in terms of properly returning a set of lat/long values from my function utilizing Google's geocoding API which takes an address and converts it into a lat,lang format which I can pass into Youtube's API to fetch a set of videos uploaded in that general vicinity.

The fix I settled upon is to create a hidden element which gets the lat long value, and then it is passed in. The following is the html tag that I settled on:

<div class="form-group" style="display:none;">
            <label for="hidden">Extra:</label>
            <input type="text" class="form-control" id="hidden" name="maxResults" placeholder="lat,lang">
        </div>

However, my issue was that in my JavaScript, the way I originally had it, it would fail to return the value correctly. If I did an alert inside the function it would should the lat,lang values correctly. However, upon returning those values they are set as undefined for my location: Original code below:

function sendData() {
    function initMap() {
                var myLatLng = {lat: -25.363, lng: 131.044};

                var map = new google.maps.Map(document.getElementById('map'), {
                    zoom: 4,
                    center: myLatLng
                });

                var marker = new google.maps.Marker({
                    position: myLatLng,
                    map: map,
                    title: 'Hello World!'
                });
            }

  var geocoder = new google.maps.Geocoder();

//  document.getElementById('submission').addEventListener('click', function() {
//    geocodeAddress(geocoder, map);
//  });
                var myLatLng = {lat: -25.363, lng: 131.044};

                var map = new google.maps.Map(document.getElementById('map'), {
                    zoom: 4,
                    center: myLatLng
                });
    var keyword = $('#q').val();
    console.log(geocodeAddress(geocoder,map));
    var location = geocodeAddress(geocoder,map);//$('#location').val();
    var r = $('#locationRadius').val();
    var maxResult = $('#maxResults').val();

    console.log("keyword is: " + keyword);

    $.get(
        "../php/geolocation.php",
        {
            q: keyword,
            location: location,
            locationRadius: r,
            maxResults: maxResult
        },
        function (data) {
            $('#geolocation-results').html(data);
        }
    );
}

function buttonClick() {
    $("#submission").submit(function(e) {
        e.preventDefault();
    });
    sendData();
}

function geocodeAddress(geocoder, resultsMap) {
        var address = document.getElementById('location').value;
        geocoder.geocode({'address': address}, function(results, status) {
          if (status === 'OK') {
            //resultsMap.panTo(results[0].geometry.location);
            var marker = new google.maps.Marker({
              map: resultsMap,
              position: results[0].geometry.location
            });
      var lat = results[0].geometry.location.lat();
      var latS = toString(lat);
      var lng = results[0].geometry.location.lng();
      var lngS = toString(lng);
      var latlngS = latS.concat(",",lngS);
      var latlng = new google.maps.LatLng(lat, lng);
             resultsMap.setCenter(latlng);
             console.log(latlngS);
      return latlngS;
          } else {
            alert('Geocode was not successful for the following reason: ' + status);
          }
        });
      }

And below is the fix I settled upon


function geocode() {

    var myLatLng = {lat: -25.363, lng: 131.044};

    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 4,
        center: myLatLng
    });


    var geocoder = new google.maps.Geocoder();
    geocodeAddress(geocoder, map);

}

function sendData() {


//  document.getElementById('submission').addEventListener('click', function() {
//    geocodeAddress(geocoder, map);
//  });


    var keyword = $("#q").val();
    var r = $('#locationRadius').val();
    var maxResult = $('#maxResults').val();
    var location = $("#hidden").val();


    console.log("keyword is: " + keyword);

    $.get(
        "../php/geolocation.php",
        {
            q: keyword,
            location: location,
            locationRadius: r,
            maxResults: maxResult
        },
        function (data) {
            $('#geolocation-results').html(data);
        }
    );
}

function buttonClick() {
    $("#submission").submit(function(e) {
        e.preventDefault();
    });
    sendData();
}

function geocodeAddress(geocoder, resultsMap) {


    var address = document.getElementById('location').value;
    geocoder.geocode({'address': address}, function (results, status) {
        if (status === 'OK') {
            resultsMap.setCenter(results[0].geometry.location);
            var marker = new google.maps.Marker({
                map: resultsMap,
                position: results[0].geometry.location
            });
            var latS = results[0].geometry.location.lat().toString();
            var lngS = results[0].geometry.location.lng().toString();
            //alert((results[0].geometry.location.lat()));
            var latLang = latS.concat(',', lngS);
            $('#hidden').val(latLang);
            console.log($('#hidden').val());

        } else {
            alert('Geocode was not successful for the following reason: ' + status);
        }
    });
}

The geocode function is called via an onblur in my html:

<div class="form-group">
            <label for="location">location</label>
            <input type="text" class="form-control" id="location" name="location" placeholder="Athens, GA" onblur="geocode()">
        </div>

So really, to wrap up a rather lengthy code, I want to know how I can avoid having to maintain this disgusting fix in terms of having a hidden in-between form element? Apologies if this is a poorly worded question, I tried my best.

Paul
  • 26,170
  • 12
  • 85
  • 119
SomeStudent
  • 2,856
  • 1
  • 22
  • 36
  • This [previous answer](http://stackoverflow.com/a/14220323/103081) explains what is happening and basically suggests that code should be rewritten to process the data only in the callback function because only when the callback is called does the data actually exist. – Paul Mar 09 '17 at 17:15
  • I see, thank you for the link, so even though the geocode function for changing the address occurs before in order of execution prior to the ajax function it still won't be counted? – SomeStudent Mar 09 '17 at 17:21
  • as always, uncertain of the -1. Like ninja downvoters who refuse to provide useful feedback. – SomeStudent Mar 09 '17 at 18:40

1 Answers1

1

If you want sendData() to be called automatically with the location data as soon as the latLang in geocode's callback is available, then you could:

  1. add a parameter to the function definition as in function sendData(location) and remove the var location = ... initialization and the hidden element because location will instead be set as a parameter to sendData; and
  2. call sendData(latlang) in geocode's anonymous function callback instead of setting the hidden value, on the line where you are currently setting hidden.

The idea is to create a function that can be called in the geocode callback and consume its latlang data there instead of storing it globally.

Alternatively, you could set a global variable in a callback instead of the value of a hidden element, but then you can't use it until it is defined. That's no good for automatically chaining the steps, but might be ok if a human watches and pushes a button for the next step. Like the usage of hidden element values, it can lead to synchronization issues.

Paul
  • 26,170
  • 12
  • 85
  • 119
  • yeah, I tried the global variable by setting var location, but that also did not work. I will look into your first suggestion as soon as I can. – SomeStudent Mar 09 '17 at 17:32