Problem when using 2 javascript API of google maps in the same index.html

0

I'm wanting to load 2 maps with the google application in the same index.html. The maps when tested one by one have no problem, both are loaded and work properly.

The first map shows the user's location in <div id="map"> as follows:

mapa 1

var map, infoWindow;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 13,
    zoomControl: false,
    mapTypeControl: false,
    scaleControl: false,
    streetViewControl: false,
    rotateControl: false,
    fullscreenControl: false,


    styles: [{
        "featureType": "administrative.country",
        "elementType": "labels.text.stroke",
        "stylers": [{
          "weight": 1.5
        }]
      },
      {
        "featureType": "administrative.land_parcel",
        "stylers": [{
          "visibility": "off"
        }]
      },
      {
        "featureType": "administrative.neighborhood",
        "stylers": [{
          "visibility": "off"
        }]
      },
      {
        "featureType": "landscape.natural.terrain",
        "stylers": [{
          "saturation": 40
        }]
      },
      {
        "featureType": "poi",
        "stylers": [{
            "saturation": 25
          },
          {
            "visibility": "simplified"
          },
          {
            "weight": 2
          }
        ]
      },
      {
        "featureType": "poi.attraction",
        "stylers": [{
          "visibility": "off"
        }]
      },
      {
        "featureType": "poi.business",
        "stylers": [{
          "visibility": "off"
        }]
      },
      {
        "featureType": "road",
        "elementType": "labels",
        "stylers": [{
          "visibility": "on"
        }]
      },
      {
        "featureType": "transit.line",
        "stylers": [{
            "color": "#5485c0"
          },
          {
            "visibility": "on"
          }
        ]
      },
      {
        "featureType": "water",
        "elementType": "geometry.fill",
        "stylers": [{
            "color": "#5485c0"
          },
          {
            "saturation": 40
          },
          {
            "lightness": 15
          }
        ]
      },
      {
        "featureType": "water",
        "elementType": "labels.text",
        "stylers": [{
          "visibility": "on"
        }]
      }
    ]
  });
  infoWindow = new google.maps.InfoWindow;

  // Try HTML5 geolocation.
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(function(position) {
      var pos = {
        lat: position.coords.latitude,
        lng: position.coords.longitude
      };

      marker = new google.maps.Marker({
        map: map,
        draggable: true,
        animation: google.maps.Animation.DROP,
        position: {
          lat: pos.lat,
          lng: pos.lng
        },
        title: 'Hey! Estas aquí'
      });

      map.setCenter(pos);
    }, function() {
      handleLocationError(true, infoWindow, map.getCenter());
    });
  } else {
    // Browser doesn't support Geolocation
    handleLocationError(false, infoWindow, map.getCenter());
  }
}

function handleLocationError(browserHasGeolocation, infoWindow, pos) {
  infoWindow.setPosition(pos);
  infoWindow.setContent(browserHasGeolocation ?
    'Error: The Geolocation service failed.' :
    'Error: Your browser doesn\'t support geolocation.');
  infoWindow.open(map);
}
html,
body {
  height: 100%;
  width: 100%;
  padding: 0;
}

#map {
  width: 100%;
  height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
  <div id="map"></div>
  <script async defer src="https://maps.googleapis.com/maps/api/js? key=AIzaSyBhSrbK0MeReqvKKFaK1umUYL_LDGSYBwg&callback=initMap">
  </script>
  
</body>

The second function loads a GMAP of the javascript API in a <div id='map2'> that has the quality of being able to drag the marker and saves the coordinates in a <input type="text" id='coords'>

mapa 2

var marker;          //variable del marcador
var coords = {};    //coordenadas obtenidas con la geolocalización

 

//Funcion principal
initCoords = function () 
{

    //usamos la API para geolocalizar el usuario
        navigator.geolocation.getCurrentPosition(
          function (position){
            coords =  {
              lng: position.coords.longitude,
              lat: position.coords.latitude
            };
            setMapa(coords);  //pasamos las coordenadas al metodo para crear el mapa
            
           
          },function(error){console.log(error);});
    
}



function setMapa (coords)
{   
      //Se crea una nueva instancia del objeto mapa
      var map = new google.maps.Map(document.getElementById('map2'),
      {
        zoom: 13,
        center:new google.maps.LatLng(coords.lat,coords.lng),

      });

      //Creamos el marcador en el mapa con sus propiedades
      //para nuestro obetivo tenemos que poner el atributo draggable en true
      //position pondremos las mismas coordenas que obtuvimos en la geolocalización
      marker = new google.maps.Marker({
        map: map,
        draggable: true,
        animation: google.maps.Animation.DROP,
        position: new google.maps.LatLng(coords.lat,coords.lng),

      });
      //agregamos un evento al marcador junto con la funcion callback al igual que el evento dragend que indica 
      //cuando el usuario a soltado el marcador
      marker.addListener('click', toggleBounce);
      
      marker.addListener( 'dragend', function (event)
      {
        //escribimos las coordenadas de la posicion actual del marcador dentro del input #coords
        document.getElementById("coords").value = this.getPosition().lat()+","+ this.getPosition().lng();
      });
}

//callback al hacer clic en el marcador lo que hace es quitar y poner la animacion BOUNCE
function toggleBounce() {
  if (marker.getAnimation() !== null) {
    marker.setAnimation(null);
  } else {
    marker.setAnimation(google.maps.Animation.BOUNCE);
  }
}

      function abrirGmap {
      $('#modalGmap').on('shown.bs.modal',function(){

          initCoords();
          console.log("si");
      })
    }
html, body {

width: 100%;
height: 100%;
padding:0;
margin: 0;

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>

<!-- comienzo del input id='coords' -->

<input id="coords" type="text" class="form-control" value="Ubicación" data-toggle="modal" data-target="#modalGmap"/>

<!-- Comienzo del modal -->

<div class="modal fade" id="modalGmap" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
						      <div class="modal-dialog modal-dialog-centered" role="document" style="width: 60%; height: 60%;">
						        <div id="map2" class="modal-content" style="width: 100%; height: 100%;">
						          <div class="modal-header">
						            <h5 class="modal-title" id="exampleModalLongTitle">Modal title</h5>

						            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
						              <span aria-hidden="true">&times;</span>
						            </button>
						          </div>
						          <div class="modal-body">
						          </div>
						        </div>
						      </div>
						    </div>
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBhSrbK0MeReqvKKFaK1umUYL_LDGSYBwg">
    </script>
 </body>

The problem seems to be that when loading the google API key, it does a callback = Function (), which directly calls the function when it is loaded, referring to only one of the two functions.

Things I tried:

I tried to delete the callback = initMap and call the function when the user clicks on the <input id="coords"> but when I do this only the map 2 works and the first one stops working.

I tried to delete both Javascript functions of the index.html and separate them into 2 different javascript files and in the index.html create a function of the type

Function initMaps {
    
    window.onload = function initMap();
    window.onload = function initCorrds();
  
}

 <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBhSrbK0MeReqvKKFaK1umUYL_LDGSYBwg">
  </script>

I thought that by calling the files mapa1.js and mapa2.js between <head></head> when it arrived at the script and the web finished loading the functions would start ... but it did not work.

I also tried with the tag onclick=function() and onload=function() in the respective divs where the maps should be loaded ... but it did not work.

Well that has been more or less everything. I hope someone can help me solve!

Thank you very much

NEW TESTS TO 12/17/2018

Based on the response of a user I tried to separate both functions into 2 different files gmap.js and GPSservice.js . Then in index.html I call both files between <head></head> con <script src js/gmap.js etc. Then before ending the </body> and below the script of the google API create the following function

<script>
    function abrirGmap {

        initMap();
        initCoords();
    }

    window.onload = abrirGmap;

</script>

I expected that with this function after loading the files in the head and "encapsulate" both functions in a "trigger function" that would be loaded by window.onload = abrirGmap; . The result: It did not work.

The next attempt was to remove the window.onload = abrirGmap; of the trigger function and add a callback=abrirGmap to the google API script. as follows.

<script async defer src="https://maps.googleapis.com/maps/api/js? key=AIzaSyBhSrbK0MeReqvKKFaK1umUYL_LDGSYBwg&callback=abrirGmap">

the result: it did not work.

FINAL SOLUTION

I will separate both functions in different ways as mentioned above. then I call them in the head of index.html as mentioned above and at the end before the body encapsulates the functions and I execute as follows.

<script>

    function abrirGmap() {

        initMap();
        initCoords();
    }

</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBhSrbK0MeReqvKKFaK1umUYL_LDGSYBwg&callback=abrirGmap">
</script>
    
asked by Macali 16.12.2018 в 20:29
source

1 answer

1

You have several problems

First: If you want to rendererize two maps on the same page, you do not need to call the API script twice. Once enough. Twice it will generate unexpected behaviors at least. You also do not need to load jQuery twice.

Second Your first call to the API is passing as a parameter the function that will be executed when it finishes loading the API script , which has absolutely nothing to do with the moment you finish loading the DOM. Therefore you do not get anything trying to put that behavior in window.onload .

Third Even if it makes sense to homologate the load of the google maps API script to window.onload , when you put:

window.onload = function initMap();
window.onload = function initCorrds();

The second statement steps on the first. And that's not to mention that syntactically that does not mean anything. To invoke a function, do not precede it with function .

Room:

If you completely forget about the event window.onload and you limit yourself to define a function that triggers the other two (and you use the following corrected syntax)

function initMaps() {
   initMap();
   initCoords();
}

You need someone or something to invoke it, so it would be time to re-add your callback in the API call ( which is the only call you make, forget about doing 2 ):

<script async defer
src="https://maps.googleapis.com/maps/api/js?callback=initMaps&key=AIzaSyBhSrbK0MeReqvKKFaK1umUYL_LDGSYBwg">

Also I would change the name of initMaps because it looks a lot like initMap . I'd better put initDosMapas or something very obvious.

Fifth (this is not a blocking problem)

You are declaring a global variable map at the beginning of your script.

var map, infoWindow;

function initMap() { ... }

And then you do shadowing of this on your second map:

function setMapa (coords)
{   
  //Se crea una nueva instancia del objeto mapa
  var map = new google.maps.Map(document.getElementById('map2'),
  {
    zoom: 13,
    center:new google.maps.LatLng(coords.lat,coords.lng),

  });

 ...
}

In doing so, the reference to the variable is lost in some areas, and that can lead to confusion.

    
answered by 17.12.2018 / 13:41
source