0

I am working on a hybrid app using the Appgyver Steroids framework and I'm trying to implement a 'detect user location' feature whereby the user can toggle a switch to choose whether they'd like their location (long & lat) to be detected automatically, or alternatively they can enter their location (city, postcode or county) into a text box and the longitude and latitude will be calculated on click of a button based on their input/selection.

When the user toggles the switch into the 'on' position and taps submit, the navigator.geolocation.getCurrentPosition is fired and calls the relevant functions which then stores their current longitude and latitude in localStorage. This works perfectly.

However, when the user toggles the switch into the 'off' position, my geocode function [manuallyGeoCode()] which codes their location into long and lat doesn't seem to fire in time and so the alert is fired straight after calling that geocode function before it has had time to actually set the localStorage value. I've researched using a callback and I've looked into using the jQuery deferred method, both of which I've had no success with using. Any help would be massively appreciated! Thanks for reading.

Here's my code:

    <h3>Your location</h3>
      <ul class="list">
        <li class="item item-toggle">Use my current location
          <label class="toggle toggle-balanced">
            <input type="checkbox" id="myLocationToggle" checked="true">
            <div class="track">
              <div class="handle"></div>
            </div>
          </label>
        </li>
        <li class="item item-input">
          <input type="text" id="userLocation" placeholder="City, town or postcode" disabled="true">
        </li>
      </ul>

<button class="button button-balanced" id="getLongLat">Get long/lat</button>


$(function(){
  AutoGeoCode(); 
});

function AutoGeoCode(){
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(onSuccess, onError);
  }
}

$('#getLongLat').on('click',function(){
  localStorage.latToPost = '';
  localStorage.lngToPost = '';

  if(localStorage.userLatAutoDetected != '0' || localStorage.userLngAutoDetected != '0'){
    localStorage.latToPost = localStorage.userLatAutoDetected;
    localStorage.lngToPost = localStorage.userLngAutoDetected;
  }
  else{
    manuallyGeoCode(); // this doesn't finish in time so it jumps to the alert below and shows empty values.
  }

  alert('geodata is: {'+localStorage.latToPost+'}, {'+localStorage.lngToPost+'}');

});

$('#myLocationToggle').on('click',function(){
  if($(this).is(':checked')){
    $('#userLocation').val('').prop('disabled',true);
    AutoGeoCode();
  }
  else{
    $('#userLocation').val('').prop('disabled',false);
    localStorage.userLatAutoDetected = '0';
    localStorage.userLngAutoDetected = '0';
  }
});

function onSuccess(position){
    localStorage.userLatAutoDetected = position.coords.latitude;
    localStorage.userLngAutoDetected = position.coords.longitude;
}

function onError(error){
  alert('current location could not be auto detected. Error: ' + error);
}

//Autocomplete location search box
function initialize() {
  var address = (document.getElementById('userLocation'));
  var autocomplete = new google.maps.places.Autocomplete(address);
      autocomplete.setTypes(['geocode']);
  google.maps.event.addListener(autocomplete, 'place_changed', function() {
  var place = autocomplete.getPlace();
    if (!place.geometry) {
      return;
    }
  var address = '';
    if (place.address_components) {
      address = [
                  (place.address_components[0] && place.address_components[0].short_name || ''),
                  (place.address_components[1] && place.address_components[1].short_name || ''),
                  (place.address_components[2] && place.address_components[2].short_name || '')
                ].join(' ');
    }
  }); //end google.maps.event
}

function manuallyGeoCode(){
  var address = $('#userLocation').val();
  geocoder = new google.maps.Geocoder();
    geocoder.geocode({'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        localStorage.latToPost = results[0].geometry.location.lat();
        localStorage.lngToPost = results[0].geometry.location.lng();
      }
      else {
        alert('Your location could not be geocoded.');
      }
    });
}

google.maps.event.addDomListener(window, 'load', initialize);
user1163073
  • 307
  • 7
  • 20
  • sending a diff callback to manuallyGeoCode and calling the same in geocoder.geocode's callback should help – Sunand Sep 03 '14 at 19:38
  • @Sunand - I've just tried it, it still fires the alert and produces "geodata is: {}, {}". Is it because I'm calling `manuallyGeoCode()` within the the if{}..else{}.. block? – user1163073 Sep 03 '14 at 19:49

1 Answers1

0

Please find the difference in the handle and the manual geocode functions

$('#getLongLat').on('click',function(){
  localStorage.latToPost = '';
  localStorage.lngToPost = '';

  if(localStorage.userLatAutoDetected != '0' || localStorage.userLngAutoDetected != '0'){
    localStorage.latToPost = localStorage.userLatAutoDetected;
    localStorage.lngToPost = localStorage.userLngAutoDetected;
    alert('geodata is: {'+localStorage.latToPost+'}, {'+localStorage.lngToPost+'}');
  }else{
    manuallyGeoCode(function(){
      alert('geodata is: {'+localStorage.latToPost+'},{'+localStorage.lngToPost+'}');

    }); // this doesn't finish in time so it jumps to the alert below and shows empty values.
  }
});

function manuallyGeoCode(cb){
  var address = $('#userLocation').val();
  geocoder = new google.maps.Geocoder();
    geocoder.geocode({'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        localStorage.latToPost = results[0].geometry.location.lat();
        localStorage.lngToPost = results[0].geometry.location.lng();
        cb();
      }
      else {
        alert('Your location could not be geocoded.');
      }
    });
}
Sunand
  • 703
  • 4
  • 9
  • This alerted the correct geodata however when I alert `localStorage.latToPost` or `localStorage.lngToPost` outside the if{}..else{}.. it still shows an alert but without the geodata. If that makes sense? Reason being, I want to post the localStorage data via ajax to my web service. – user1163073 Sep 03 '14 at 20:05
  • so where ever u are using alert, there use a custom function to take these values as args and send the request in there – Sunand Sep 03 '14 at 20:07
  • Thanks for your help. The issue is, when I place an `$.ajax` request after the `if else` block, the `ajax` block will be executed before `manuallyGeoCode` has a chance to callback the geodata and store those values in `localStorage`. – user1163073 Sep 03 '14 at 20:53