Because the variable City1 does not save the value in the first execution of the modal, and on the contrary in the second execution if it does

1

document.getElementById("BtnModal").onclick = Public;

Ciudad1 = "";

function Publication(){
	navigator.geolocation.getCurrentPosition(showPosition);
	function showPosition(position){
		var geocoder = new google.maps.Geocoder();
		lat=position.coords.latitude;
		lon=position.coords.longitude;
		latlonmarker= new google.maps.LatLng(lat, lon);
		geocoder.geocode({ 'latLng': latlonmarker },geocoderact);
		}
		return Ciudad1;
 }

 function geocoderact(results, status){
	if (status == google.maps.GeocoderStatus.OK) {
		if (results[0]) {
		Ciudad= results[0].address_components[4].long_name;
		Ciudad1 = Ciudad;

		} else {
		error('Google no retorno resultado alguno.');
		}
		} else {
		error("Geocoding fallo debido a : " + status);
		}

}

function Public(){
	var Resul=Publication();
	alert(Resul);
	$.ajax({
        url: "Public.html",
        type: "post",
        dataType: "html",
        cache: false,
        contentType: false,
        processData: false,
			success : function(data) {
				console.log("SUCCESS: ", data);
				display(data);
			},
			error : function(e) {
				console.log("ERROR: ", e);
				display(e);
			},
			done : function(e) {
				console.log("DONE");
			}
		});
}

function display(data) {
	var info = "<h4>Ajax Response</h4><pre>"
			+ data + "</pre>";
	$('#Barrio').html(info);
}
    
asked by Mario Garcia 10.11.2016 в 06:55
source

1 answer

2

Let's examine your code:

function Publication(){
    navigator.geolocation.getCurrentPosition(showPosition);
    function showPosition(position){
        var geocoder = new google.maps.Geocoder();
        lat=position.coords.latitude;
        lon=position.coords.longitude;
        latlonmarker= new google.maps.LatLng(lat, lon);
        geocoder.geocode({ 'latLng': latlonmarker },geocoderact);
        }
        return Ciudad1;
 }

It is noted that the call to your function geocoderact is a callback ; that is, it is asynchronous and does not run in the order in which you believe; your Publication function returns City1 before that your geocoderact function modifies it.

The exact behavior of your code is:

  • ... several actions ...
  • we place the call to geocoderact in the pending event queue.
  • ... other actions ...
  • we return City1, which has not yet been modified.
  • Resto de código a ejecutar hasta que lleguemos al return final ...

    When you reach the last return and finish the sequential code execution completely, then ...

  • The browser processes pending events.
  • One of those events is your call to geocoderact()
  • geocoderact() changes the value of your variable City1.
  • The new value is now available.
  • The browser continues processing other pending events.
  • one of those other pending events is your new button click, where you access Ciudad1 which, now, has already been modified.
  • In fact, if you look at the results your page offers you, every time you press the button it will show you the result of the previous click .

    In the Mozilla Developer Network they explain it in detail: link

    EDITO

    callbacks ARE INEVITABLE in Javascript , due to their own event-oriented nature; use any code that works with the network or with user events; the expression callbacks hell (hell of callbacks ) refers to the difficulty of programming in this way, which makes it difficult to know exactly where we are, how we got here , and where will we go next.

    In this particular case, the no changes are to eliminate the callbacks , which is impossible since they are used by the geocoder object and we do not know anything about it. The solution is to convert our functions into callback functions, that is, change our programming mode from linear to event-oriented :

    For this, we have the function setTimeout( FUNCTION, TIME ) . Simply using setTimeout( FunciónALlamar, 0 ) creates a new event that is placed at the end of the queue, and the browser will process it when it can.

    The previous code could be modified in the following way:

    function Publication(){
      . . .
      latlonmarker= new google.maps.LatLng(lat, lon);
      geocoder.geocode({ 'latLng': latlonmarker },geocoderact);
     }
    }
    

    We eliminate the return , which is useless.

    function geocoderact(results, status){
     if (status == google.maps.GeocoderStatus.OK) {
      if (results[0]) {
       Ciudad= results[0].address_components[4].long_name;
       Ciudad1 = Ciudad;
       setTimeout( ShowResult, 0 ); // Llamamos a nuestro propio callback.
      } else {
       error('Google no retorno resultado alguno.');
      }
     } else {
      error("Geocoding fallo debido a : " + status);
     }
    }
    

    If all went well, we called our own callback , to show us the result.

    function ShowResult( ) {
     alert( Ciudad1 );
    }
    

    We show the result, or do anything else.

    function Public( ) {
     setTimeout( Publication, 0 ); // Que se ejecute cuando el navegador pueda.
     $.ajax( {
      url: "Public.html",
      . . .
    

    We no longer need the variables.

        
    answered by 10.11.2016 / 07:55
    source