Finally getting around to fixing the well-known problem "API Key" error on a Google map I created back in 2014 (before you needed an API key for Google Maps API). I obtained a key and put this in the <head> (obviously substituting the real key for MY_API_KEY):
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=MY_API_KEY&callback=initMap">
</script>
and taking out the old <body onLoad="initMap()"> leaving just the <body> tag.
The map, which used to work while just warning me about the API key, now fails almost completely (shows the background map but none of the markers that should be on it), with first an error in the Chrome dev tools saying that I am using the API key multiple times ("You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors."), and then a lot of errors along this line:
InvalidValueError: setPosition: not a LatLng or LatLngLiteral: in property lat: not a number
InvalidValueError: setMap: not an instance of Map; and not an instance of StreetViewPanorama
A lot of the code is based on markers with labels.
Also have a bunch of infowindows along this line:
var intertidalObj = {
"Intertidal":{name:"Intertidal", infowindow: new google.maps.InfoWindow({maxWidth:520, position: new google.maps.LatLng(48.69176776907712, -122.90861248970032),
content: "<p class='iw'><strong>Intertidal Community</strong><br>The intertidal zone, also known as the foreshore and seashore, is the area that is above water at low tide and under water at high tide (in other words, the area between tide marks). This area can include many different types of habitats, with many types of animals, such as sea stars, sea cucumbers, sea urchins, crabs, barnacles, octopus, squid, anemones and worms.<br><br><a href='http://www.kwiaht.org' target='_blank'>Kwiáht</a> and <a href='http://www.irthlingz.org' target='_blank'>Irthlingz</a> are currently working with Laura Tidwell’s Orcas Middle School marine science students to create an interactive map of Indian Island's rich and fascinating intertidal community.<br><br><img class='pic' src='http://www.monumentalmap.com/monumentalmap/indian_island/intertidal.jpg'><br>Sources: <a href='https://sites.google.com/site/indianislandproject/identification-guides/birds' target='_blank'>Kwiaht</a> and <a href='http://en.wikipedia.org/wiki/Intertidal_zone' target='_blank'>Wikipedia</a></p><br>"}),coordinates:[48.69176776907712, -122.90861248970032]}
};
google.maps.event.addListener(intertidalObj["Intertidal"].infowindow,'closeclick',function(){
document.getElementById("Intertidal").checked = false;
});
I also tried putting the async defer inside the <body> instead of in the <head>.
That didn't work, and from my Googling, it seems the <head> is the right place. Any suggestions? I'm not aware of any other options to try.
edit: @geocodezip: Your suggestion seems correct, but after I eliminated the line you suggest, I got the following errors in Chrome dev tools:
Uncaught ReferenceError: google is not defined
at eval (eval at <anonymous> (markerwithlabel.min.js:1), <anonymous>:1:641)
at markerwithlabel.min.js:1
VM25:1 Uncaught (in promise) TypeError: MarkerLabel_.getSharedCross is not a function
at new MarkerLabel_ (eval at <anonymous> (markerwithlabel.min.js:1), <anonymous>:1:601)
at new MarkerWithLabel (eval at <anonymous> (markerwithlabel.min.js:1), <anonymous>:1:9546)
at initMap ((index):171)
at js?key=MY_API_KEY&callback=initMap:125
at js?key=MY_API_KEY&callback=initMap:125
Since it was saying that google was not defined, I thought maybe I needed to move the async defer up to the top of the <head> section. I tried that, and got the following error:
monumentalmap.com/:1 Uncaught (in promise)
Wc {message: "initMap is not a function", name: "InvalidValueError", stack: "Error↵ at new Wc (https://maps.googleapis.com/m…&callback=initMap:125:108"}
message: "initMap is not a function"
name: "InvalidValueError"
Currently, the less functional one has the defer async near the top of the <head> and the dev console is showing:
VM511:1 Uncaught ReferenceError: google is not defined
at eval (eval at <anonymous> (markerwithlabel.min.js:1), <anonymous>:1:641)
at markerwithlabel.min.js:1
(anonymous) @ VM511:1
(anonymous) @ markerwithlabel.min.js:1
VM511:1 Uncaught (in promise) TypeError: MarkerLabel_.getSharedCross is not a function
at new MarkerLabel_ (eval at <anonymous> (markerwithlabel.min.js:1), <anonymous>:1:601)
at new MarkerWithLabel (eval at <anonymous> (markerwithlabel.min.js:1), <anonymous>:1:9546)
I have a feeling I just need to put the async defer in the right place. But not sure where that is.
What finally worked for me was:
1) eliminating
markerwithlabel.min.js2) creating an object literal (
fishObjin the sample code below) whose properties are a bunch of object literals (e.g.lingcod,threespine stickleback,tubesnout,northern clingfishandPacific sand lancebelow -- in reality there are a lot more of these), each with three properties: aname, aninfowindow, andcoordinates(latitude/longitude)3) using a for/in loop to iterate over the "container" object (
fishObj) with plain oldnew google.maps.Marker(instead ofnew MarkerWithLabelthat I used previously) to instantiate the objects on the map, at the same time adding alabelproperty (as well as some other properties) to each object. (Most of these properties are left over from my previous approach, and some may no longer be necessary or have any effect. One that does work istitlewhich creates a tooltip.)4) continuing to use
async defer:Check out the map here: http://monumentalmap.com.s3-website-us-west-2.amazonaws.com/
Here's some sample code:
Hoping this might help someone facing the same problems.