Problem when creating a map using Google Maps' API and geolocation
Asked Answered
H

4

10

I have to create a map that returns the location of a client using Google Maps API, it's for an assignment.

The code works fine, it locates the longitude and latitude and prints it on screen, pbut when it's time to create the map throws me this error: message: "Map: Expected mapDiv of type Element but was passed null. name: InvalidValueError"

Does anyone know why that appears since I did specify mapDiv map = new google.maps.Map(document.getElementById("map"), {center: {lat: latitud, lng: longitud}, zoom: 14});...

var longitud;
var latitud;

var options = {
    enableHighAccuracy: true,
    timeout: 5000,
    maximumAge: 0
};
  
function success(pos) {
    var crd = pos.coords;
    latitud = crd.latitude
    longitud = crd.longitude   
    document.getElementById("latitud").innerHTML = latitud 
    document.getElementById("longitud").innerHTML = longitud 
};
  
function error(err) {
    document.getElementById("map").innerHTML = ('ERROR(' + err.code + '): ' + err.message);
};
  
navigator.geolocation.getCurrentPosition(success, error);

function initMap(){
    map = new google.maps.Map(document.getElementById("map"), {
        center: {lat: latitud, lng: longitud},
        zoom: 14
    });
}
.map{
    margin: 0 auto;
    width: 300px;
    height: 300px;
}
<head>
        <meta charset="utf-8">
        <script type="text/javascript" src="funciones.js"></script>
        <script src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initMap"></script>
        <link rel="stylesheet" type="text/css" href="style.css">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
        <title>Tcuida</title>
</head>
    
<div class="paginaPrinc" id="paginaPrinc">
    <div id="latitud"></div>
    <div id="longitud"></div>
    <div id="map" class="map"></div>
</div>
Hydrocellulose answered 4/7, 2020 at 1:57 Comment(0)
G
4

I get a different error with the posted code: InvalidValueError: setCenter: not a LatLng or LatLngLiteral with finite coordinates: in property lat: not a number, because the geolocation service is asynchronous, and the map is created before it returns a result.

You have a race condition between two asynchronous operations:

  1. the load of the Google Maps Javascript API v3, which calls initMap
  2. the return of the results of the geolocation service, which calls success

Best would be to remove the race condition, either have the geolocation function call initMap or have the initMap function make the geolocation request.

Example of the second option:

function initMap(){
    navigator.geolocation.getCurrentPosition(success, error);
}

function success(pos) {
    var crd = pos.coords;
    latitud = crd.latitude
    longitud = crd.longitude   
    document.getElementById("latitud").innerHTML = latitud 
    document.getElementById("longitud").innerHTML = longitud 
    map = new google.maps.Map(document.getElementById("map"), {
        center: {lat: latitud, lng: longitud},
        zoom: 14
    });
};

working example

proof of concept fiddle

code snippet:

var longitud;
var latitud;

var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0
};

function success(pos) {
  var crd = pos.coords;
  latitud = crd.latitude
  longitud = crd.longitude
  document.getElementById("latitud").innerHTML = latitud
  document.getElementById("longitud").innerHTML = longitud
  map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: latitud,
      lng: longitud
    },
    zoom: 14
  });
};

function error(err) {
  document.getElementById("map").innerHTML = ('ERROR(' + err.code + '): ' + err.message);
};

function initMap() {
  navigator.geolocation.getCurrentPosition(success, error);
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

.map,
.paginaPrinc {
  height: 80%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div class="paginaPrinc" id="paginaPrinc">
  <div id="latitud"></div>
  <div id="longitud"></div>
  <div id="map" class="map"></div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
Gertrudegertrudis answered 4/7, 2020 at 3:1 Comment(0)
A
9

This occurs when document.getElementById("map") returns null or type other than div.

map = new google.maps.Map(element, options)

The 1st parameter in the function expects element of div type

Ambi answered 6/4, 2021 at 9:59 Comment(1)
Instead of div you probably meant Element (or HTMLElement or HTMLDivElement).Sulphonamide
G
4

I get a different error with the posted code: InvalidValueError: setCenter: not a LatLng or LatLngLiteral with finite coordinates: in property lat: not a number, because the geolocation service is asynchronous, and the map is created before it returns a result.

You have a race condition between two asynchronous operations:

  1. the load of the Google Maps Javascript API v3, which calls initMap
  2. the return of the results of the geolocation service, which calls success

Best would be to remove the race condition, either have the geolocation function call initMap or have the initMap function make the geolocation request.

Example of the second option:

function initMap(){
    navigator.geolocation.getCurrentPosition(success, error);
}

function success(pos) {
    var crd = pos.coords;
    latitud = crd.latitude
    longitud = crd.longitude   
    document.getElementById("latitud").innerHTML = latitud 
    document.getElementById("longitud").innerHTML = longitud 
    map = new google.maps.Map(document.getElementById("map"), {
        center: {lat: latitud, lng: longitud},
        zoom: 14
    });
};

working example

proof of concept fiddle

code snippet:

var longitud;
var latitud;

var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0
};

function success(pos) {
  var crd = pos.coords;
  latitud = crd.latitude
  longitud = crd.longitude
  document.getElementById("latitud").innerHTML = latitud
  document.getElementById("longitud").innerHTML = longitud
  map = new google.maps.Map(document.getElementById("map"), {
    center: {
      lat: latitud,
      lng: longitud
    },
    zoom: 14
  });
};

function error(err) {
  document.getElementById("map").innerHTML = ('ERROR(' + err.code + '): ' + err.message);
};

function initMap() {
  navigator.geolocation.getCurrentPosition(success, error);
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */

.map,
.paginaPrinc {
  height: 80%;
}


/* Optional: Makes the sample page fill the window. */

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
<div class="paginaPrinc" id="paginaPrinc">
  <div id="latitud"></div>
  <div id="longitud"></div>
  <div id="map" class="map"></div>
</div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap" async defer></script>
Gertrudegertrudis answered 4/7, 2020 at 3:1 Comment(0)
S
4

You need to add a div with id "map". Else document.getElementById("map") will return null so you will get that error.

    <div id="map" style="width: auto; height: 550px; position: relative; overflow: hidden;"></div>
Seato answered 4/8, 2021 at 9:54 Comment(0)
L
0

when you try to get the element ID, need to fully load the page. Otherwise, in the script part, it cannot find the html element. Correction: window.onload=function(){ inimap(){}}

Lapse answered 4/12, 2022 at 12:30 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Judyjudye

© 2022 - 2024 — McMap. All rights reserved.