Google maps API: map doesn't load every time (Uncaught (in promise) InvalidValueError)

57 views Asked by At

I built a contact form in which a user can find his house via Google Maps and afterwards adjust the exact position via marker so that this information will be sent to my WPForms as static image together with pre-filled address details.

Everything works like expected, but there is this strange problem that the google map won't always load. It happens in every browser, beside Safari, sometimes it loads, sometimes it doesn't. I can refresh the page a few times and I'd say that it works 4 out of 5 times. When the map is not able to load, this is what the console is showing:

Uncaught (in promise) InvalidValueError: Map: Expected mapDiv of type HTMLElement but was passed null.

This is my script (I've randomized the api key)

<script src="https://maps.googleapis.com/maps/api/js?key=AIzaS1234567890hIP123456789051hbRgLF0UM&libraries=places&callback=initMap" 
        async defer></script>
<script>
var map;
var autocomplete;
var marker;
var hintDiv;

function initMap() {
    // Initialisiere die Karte
    map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: 51.1657, lng: 10.4515},
        zoom: 6,
        mapTypeId: 'roadmap',
        mapTypeControl: false,
        streetViewControl: false,
        tilt: 0
    });

    // Autocomplete-Feld
    var input = document.getElementById('addressInput');
    autocomplete = new google.maps.places.Autocomplete(input);

    // Kein Browser-Autocomplete
    input.setAttribute('autocomplete', 'off');

    // Marker
    marker = new google.maps.Marker({
        position: {lat: 0, lng: 0},
        map: map,
        draggable: true
    });

    // Listener für Autocomplete-Auswahl
    autocomplete.addListener('place_changed', function() {
        var place = autocomplete.getPlace();
        if (!place.geometry) {
            console.error("Returned place contains no geometry");
            return;
        }

        // Zentriere die Karte und setze den Marker an die ausgewählte Position
        map.setCenter(place.geometry.location);
        marker.setPosition(place.geometry.location);

        // Ändere die Kartenansicht auf Sattelitenbild
        map.setMapTypeId('satellite');
        map.setZoom(19);

        // WPForms Autofill
        updateFormFields(place);

        // Hinweis für Stecknadel
        showHint();

        // Image Export für Formular
        showImageMap();
    });

    // Listener für Marker-Bewegung
    marker.addListener('dragend', function(event) {
        // Debug 
        console.log('Marker position:', event.latLng.lat(), event.latLng.lng());
        // Geocode für Adresse des Markers
        geocodeLatLng(event.latLng, function() {
            // Update Image Export
            showImageMap();
        });
    });
}

function updateFormFields(place) {
    // WPForms Autofill
    document.getElementById('wpforms-1307-field_10').value = getPostalCode(place);
    document.getElementById('wpforms-1307-field_11').value = getCity(place);
    document.getElementById('wpforms-1307-field_12').value = getStreet(place);
    document.getElementById('wpforms-1307-field_13').value = getStreetNumber(place);
}

function getPostalCode(place) {
    // Extrahiere PLZ
    for (var i = 0; i < place.address_components.length; i++) {
        for (var j = 0; j < place.address_components[i].types.length; j++) {
            if (place.address_components[i].types[j] === 'postal_code') {
                return place.address_components[i].long_name;
            }
        }
    }
    return '';
}

function getCity(place) {
    // Extrahiere Stadt
    for (var i = 0; i < place.address_components.length; i++) {
        for (var j = 0; j < place.address_components[i].types.length; j++) {
            if (place.address_components[i].types[j] === 'locality') {
                return place.address_components[i].long_name;
            }
        }
    }
    return '';
}

function getStreet(place) {
    // Extrahiere Straße
    for (var i = 0; i < place.address_components.length; i++) {
        for (var j = 0; j < place.address_components[i].types.length; j++) {
            if (place.address_components[i].types[j] === 'route') {
                return place.address_components[i].long_name;
            }
        }
    }
    return '';
}

function getStreetNumber(place) {
    // Extrahiere Hausnummer
    for (var i = 0; i < place.address_components.length; i++) {
        for (var j = 0; j < place.address_components[i].types.length; j++) {
            if (place.address_components[i].types[j] === 'street_number') {
                return place.address_components[i].long_name;
            }
        }
    }
    return '';
}

function geocodeLatLng(latlng, callback) {
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode({'location': latlng}, function(results, status) {
        if (status === 'OK') {
            if (results[0]) {
                // ADresse formatiert
                var address = results[0].formatted_address;
                console.log('Address:', address);
                // An WPForms via static Image senden

                // Callback Bewegung Marker
                if (callback && typeof callback === 'function') {
                    callback();
                }
            } else {
                console.error('No results found');
            }
        } else {
            console.error('Geocoder failed due to: ' + status);
        }
    });
}

// Hinweis für Stecknadel
function showHint() {
    if (!hintDiv) {
        hintDiv = document.createElement('div');
        hintDiv.innerHTML = '<p>Bitte überprüfen Sie die Lage Ihres Hauses.<br>Sie können die rote Stecknadel verschieben, um Ihr Haus auszuwählen.</p>';
        hintDiv.style.backgroundColor = 'white';
        hintDiv.style.padding = '10px';
        hintDiv.style.border = '1px solid #ccc';
        hintDiv.style.borderRadius = '5px';
        hintDiv.style.marginTop = '10px';

        document.getElementById('hintContainer').appendChild(hintDiv);
    }
}
// Image Export an WPForms
function showImageMap() {
    // Erstelle ein neues Bild-Element
    var imageMap = new Image();

    // Aktualisierte Position des Markers
    var markerPosition = marker.getPosition();

    // URL für die statische Karte mit dem aktualisierten Marker
    var imageUrl = "https://maps.googleapis.com/maps/api/staticmap?" +
        "center=" + markerPosition.lat() + "," + markerPosition.lng() +
        "&zoom=19" +
        "&size=600x300" +
        "&maptype=satellite" +
        "&markers=color:yellow%7Clabel:Ihr%20Haus%7C" + markerPosition.lat() + "," + markerPosition.lng() +
        "&key=AIz1234567890QmhIP123456789051hbRgLF0UM";

    // URL für Bild
    imageMap.src = imageUrl;
document.getElementById('wpforms-1307-field_15').value = imageUrl;

    // HTML Export
    document.getElementById('imageMapContainer').innerHTML = '';
    document.getElementById('imageMapContainer').appendChild(imageMap);
}
</script>

These are my div containers:

<div>
    <input type="text" id="addressInput" placeholder="Bitte geben Sie hier Ihre Adresse ein" autocomplete="off">
</div>
<div id="map"></div>
<div id="hintContainer"></div>

thanks in advance!

tried to run it on a different server (not wordpress), expected that is has something to do with the way my theme loads the function. Did not work.

tried to remove the callback function for the eventlistener when the marker has been moved, no difference.

0

There are 0 answers