'Google is not defined' when I add directionsDisplay and Service - javascript

My map was working perfectly displaying a fixed marker, and a marker of the user's shared location. However now when I add directionsDisplay and directionsService variables along with some other code, the map doesn't load at all and I get a console error of 'google is not defined'.
Below I will post my working code, and I'll annotate all the the new lines which I added so you can tell which ones.
If I comment out the lines (as below) the map works fine and displays the console error directionsDisplay not defined, which I would expect obviously but when I add these lines in google hates me.
Also I've currently tried:
removing async defer from the api key
testing in Chrome and FF, with incognito mode and private browsing
EDIT
Thanks to #Jaromanda X, who noticed google wont be recognized until the initMap function is called so I moved the variable into calcRoute function as it didn't need to be global anyway.
I will update the code, please note that this unfortunatley doesn't make the route calculate correctly, still working on that :/
HTML:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=my key is here&callback=initMap"></script>
JS:
var directionsDisplay;
var map;
var markers = [];
var initMap = function() {
directionsDisplay = new google.maps.DirectionsRenderer();
var chesters = new google.maps.LatLng(52.19147365, -2.21880075);
map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: chesters
});
var marker = new google.maps.Marker({
position: chesters,
title: 'Chesters Restaurant',
icon: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png',
map: map
});
markers.push(marker);
directionsDisplay.setMap(map);
}
var showPosition = function(position) {
var userLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var marker = new google.maps.Marker({
position: userLatLng,
title: 'Your Location',
draggable: true,
map: map
});
markers.push(marker);
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
map.fitBounds(bounds);
calcRoute(userLatLng);
}
function calcRoute(userLatLng) {
var directionsService = new google.maps.DirectionsService();
var start = new google.maps.LatLng(userLatLng.lat, userLatLng.long),
end = new google.maps.LatLng(52.19147365, -2.21880075);
/*bounds.extend(start);
bounds.extend(end);
map.fitBounds(bounds);*/
var request = {
origin: start,
destination: end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function (response, status) {
if (status == 'OK') {
directionsDisplay.setDirections(result);
}
});
}
function errorHandler(error) {
console.log('Geolocation error : code ' + error.code + ' - ' + error.message);
}
navigator.geolocation.getCurrentPosition(showPosition, errorHandler, {
enableHighAccuracy: false,
maximumAge: 60000,
timeout: 27000
});

Have you enabled the google maps directions api? https://developers.google.com/maps/documentation/javascript/directions
I would have posted as a comment but apparently cant do that before 50rep.

Related

Doing a Google Maps reverse geocode and displaying the result as part as HTML content inside an infowindow

I have put together this script (note: I'm using jQuery 1.11.2) that gets lat long coordinates from a PHP operation (used for something else) and displays a map with a customized marker and infowindow that includes HTML for formatting the information that is displayed.
<script src="https://maps.googleapis.com/maps/api/js?v=3.20&sensor=false"></script>
<script type="text/javascript">
var maplat = 41.36058;
var maplong = 2.19234;
function initialize() {
// Create a Google coordinate object for where to center the map
var latlng = new google.maps.LatLng( maplat, maplong ); // Coordinates
var mapOptions = {
center: latlng,
zoom: 3,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
streetViewControl: false,
zoomControl: false,
mapTypeControl: false,
disableDoubleClickZoom: true
};
map = new google.maps.Map(document.getElementById("map-canvas"),mapOptions);
// CREATE AN INFOWINDOW FOR THE MARKER
var content = 'This will show up inside the infowindow and it is here where I would like to show the converted lat/long coordinates into the actual, human-readable City/State/Country'
; // HTML text to display in the InfoWindow
var infowindow = new google.maps.InfoWindow({
content: content,maxWidth: 250
});
var marker = new google.maps.Marker( {
position: latlng,
map: map,
title: "A SHORT BUT BORING TITLE",
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
infowindow.open(map,marker);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
What I'm trying to achieve is to do a reverse geocode on the coordinates stored in the latlng variable and get back the results of that in a "City, State, Country" format and insert that into the HTML for the informarker stored in the "content" variable.
Have tried multiple approaches without success. Please note that I've deliberately left out the reverse geocoding script I tried to use for clarity purposes.
Edit: I've adjusted the script presented here to comply with the rules about it being clear, readable and that it actually should work. I also include a link to a CodePen so that you can see it in action: Script on CodePen
Regarding including the script for reverse geocoding, what I did was a disaster, only breaking the page and producing "undefined value" errors. I'd like to learn the correct way of doing this by example, and that's where the wonderful StackOverflow community comes in. Thanks again for your interest in helping me out.
Use a node instead of a string as content , then you may place the geocoding-result inside the content, no matter if the infoWindow is already visible or not or when the result is available(it doesn't even matter if the InfoWindow has already been initialized, a node is always "live").
Simple Demo:
function initialize() {
var geocoder = new google.maps.Geocoder(),
latlng = new google.maps.LatLng(52.5498783, 13.42520);
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 18,
center: latlng
}),
marker = new google.maps.Marker({
map: map,
position: latlng
}),
content = document.createElement('div'),
infoWin = new google.maps.InfoWindow({
content: content
});
content.innerHTML = '<address>the address should appear here</address>';
google.maps.event.addListener(marker, 'click', function() {
infoWin.open(map, this);
});
geocoder.geocode({
location: latlng
}, function(r, s) {
if (s === google.maps.GeocoderStatus.OK) {
content.getElementsByTagName('address')[0].textContent = r[0].formatted_address;
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map-canvas"></div>
Here's how I would do it:
function reverseGeocoder(lat, lng, callback) {
var geocoder = new google.maps.Geocoder();
var point = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
geocoder.geocode({"latLng" : point }, function(data, status) {
if (status == google.maps.GeocoderStatus.OK && data[0]) {
callback(null, data[0].formatted_address);
} else {
console.log("Error: " + status);
callback(status, null);
}
});
};
And basically you would call the function like:
reverseGeocoder(lat, lng, function(err, result){
// Do whatever has to be done with result!
// EDIT: For example you can pass the result to your initialize() function like so:
initialize(result); // And then inside your initialize function process the result!
});

Update markers with current position on Google Map API

I am learning to use javascript right now with Rails and I'm having some issues with updating my markers according to my current position using AJAX. I believe the ready page:load is not running the updated coords that have been attached as a data-attribute, coords since the page is not technically reloading. How can I use my current position data and update it with events with longitude/latitude values?
var map;
$(document).on('ready page:load', function() {
if ("geolocation" in navigator) {
myMap.init();
var coords = $('#map-canvas').data('coords');
if (coords){
myMap.addMarkers(coords);
}
}
});
myMap.init = function() {
if(navigator.geolocation){
var mapOptions = {
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
navigator.geolocation.getCurrentPosition(function(position){
var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var infoWindow = new google.maps.InfoWindow({
map: map,
position: pos
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
map: map
});
map.setCenter(pos);
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
$.ajax({
url:"/all_events",
method: "GET",
data: {
latitude: latitude,
longitude: longitude
},
dataType: 'script'
});
});
} else {
document.getElementById('map-canvas').innerHTML = 'No Geolocation Support.';
}
};
myMap.addMarkers = function(coords){
var image = "http://maps.google.com/mapfiles/ms/icons/yellow-dot.png"
coords.forEach(function(coord){
var myMarker = new google.maps.Marker({
position: new google.maps.LatLng(coord.latitude, coord.longitude),
map: map,
icon: image
});
});
}
In order to make your script work in the way you want please try out the following steps:
Put your foreach loop in a function and call it at the end of your successive AJAX callbacks.
Load the AJAX once the Google Maps have finished loading completely. If Google Maps library has not finished loading than you wont be able to create a Google LatLng object, this is what is probably happening over here.
Hope this would help

How to add Markers on Google maps v3 API asynchronously?

I've been following the official documentation on how to add markers on the map so far
Nevertheless, I can see only one marker at a time max. If I try to add another one, then it doesn't work (I can't even see the first one).
My process is the following:
I initialize gmaps api:
jQuery(window).ready(function(){
//If we click on Find me Lakes
jQuery("#btnInit").click(initiate_geolocation);
});
function initiate_geolocation() {
if (navigator.geolocation)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyBbfJJVh0jL1X9b7XFDcPuV7nHD1HlfsKs&sensor=true&callback=initialize";
document.body.appendChild(script);
navigator.geolocation.getCurrentPosition(handle_geolocation_query, handle_errors);
}
else
{
yqlgeo.get('visitor', normalize_yql_response);
}
}
Then, I display it on the appropriate div. But when it comes to make the AJAX call, in order to get my locations of the different markers I'd like to display, It just doesn't work properly. Here is the code with a simple map displayed (since that's the only thing working for me so far).
function handle_geolocation_query(position){
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
mapTypeId: google.maps.MapTypeId.SATELLITE
}
alert('Lat: ' + position.coords.latitude + ' ' +
'Lon: ' + position.coords.longitude);
$('#map-canvas').slideToggle('slow', function(){
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
});
$.when( getLakes(position.coords.latitude, position.coords.longitude)).done(function(results) {
// InitializeGoogleMaps(results);
if(results)
var data = results.map(function (lake) {
//Check if the lake has any open swims, if not, the button will not be clickable and an alert will pop up
if (lake.available>0)
clickable=true;
else
clickable=false;
return {
name: lake.name,
fishs: lake.fisheryType,
swims: lake.swims,
dist: lake.distance,
lat: lake.latitude,
long: lake.longitude,
id: lake.id,
avail: lake.available,
clickable: clickable,
route: Routing.generate('lake_display', { id: lake.id, lat: position.coords.latitude, lng: position.coords.longitude})
}
});
var template = Handlebars.compile( $('#template').html() );
$('#list').append( template(data) );
} );
};
So I'd like to add markers after the AJAX call. I've set up a function that I should call in the when()
function InitializeGoogleMaps(results) {
};
to display the markers in a foreach loop but nope, can't make it work. It looks like this :
CentralPark = new google.maps.LatLng(37.7699298, -122.4469157);
marker = new google.maps.Marker({
position: location,
map: map
});
Any help would be great !
Thanks
The main issue is that the map variable is declared only in the scope of the anonymous callback on slideToggle. First of all declare at the top-level function scope.
function handle_geolocation_query(position){
var map,
mapOptions = {
zoom: 14,
center: new google.maps.LatLng(position.coords.latitude, position.coords.longitude),
mapTypeId: google.maps.MapTypeId.SATELLITE
}
...
Then change the slideToggle callback to initialise the variable instead of redeclaring:
$('#map-canvas').slideToggle('slow', function(){
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
});
Then you should pass map as a second parameter to your InitializeGoogleMaps function and call it using InitializeGoogleMaps(results, map). See where this gets you and hit me back with any questions.

Google maps v3: adding a new map when function 'failure' called

On the contact page of my site two things can happen:
The user has geolocation enabled, and a map (map-canvas) will display a route from their location to a predefined location dest. This feature works fine.
The user doesn't have geolocation enabled or chooses not to allow it. An alert will show (works fine), and some text will be added to the directions-panel (works fine). The third thing I want to happen in this scenario is a new map be added to map-canvas that is centred on dest, this feature doesn't seem to be working and I can't figure out why.
Code below should give a good representation of the above:
<script type="text/javascript">
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var dest = "Unit 20, Tallaght Business Centre, Whitestown Road, Tallaght Business Park, Ireland";//53.282882, -6.383155
var ourLocation = {lat : 53.282882, lng : -6.383155}//centre attribute of the map must be a LatLng object and not hardcoded as above
function initGeolocation() {
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition( success, failure );
}
}
//create a new map centered on user's location, display route and show directions
function success(position) {
directionsDisplay = new google.maps.DirectionsRenderer();
coords = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
}
map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById("directions-panel"));
calcRoute();
}
//calculate the route from user's location to 'dest'
function calcRoute() {
var start = coords;
var end = dest;
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
//tell user geoloc isn't enabled and just plot 'ourLocation' on 'map-canvas'
function failure() {
alert("Your browser does not have geolocation enabled so we can't give you directions to our office. Enable geolocation and try again, or consult the map for our address.");
$("#directions-error-message").css({
visibility: 'visible'
});
var destMapOptions = {
zoom:13,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(ourLocation.lat, ourLocation.lng)
}
map = new google.maps.Map(document.getElementById("map-canvas"), destMapOptions);
}
</script>
Anyone have any ideas why this isn't working? All help appreaciated.
EDIT: Working version above
You need to pass the map a LatLng object for it's centre, not an address. You will need to use Googles LocalSearch services to make that work.
var dest = {
lat : 53.282882,
lng : -6.383155
}
var destMapOptions = {
zoom:12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: new google.maps.LatLng(dest.lat,dest.lng)
}
Also, as you have map declared as a var already maybe use that rather than a function scoped variable for the map.
The center attribute of the map options must be a LatLng object. You've got it hardcoded as an address string.

Google maps API: Directions result not showing

I'm creating my own styled map using Google Maps JS API. I wanted to add directions functionality to map, i followed the official tutorial (Under Displaying the DirectionsResult title), but the final route is not appearing...
I debugged my code and I found, than directionsService.route function returns google.maps.DirectionsStatus.OK and directionsDisplay.setDirections(result) is really called with no JS error... So directions are successfully computed but not showed in my map. A tried to turn off special map styling but even on default map style it is not appearing. Any ideas where could the problem be?
OK, some code...:
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAB2gbXmG... ...mNs66iPr8&sensor=false&callback=directions_init"></script>
<script type="text/javascript">
var map;
var zoom = 11;
var directionsDisplay;
var directionsService;
function gmap_init(){
var styleArray = [ /*here is style but even if its commented its not working*/];
var alterMapStyle = new google.maps.StyledMapType(styleArray, {name: "ALTER style"});
var latlng = new google.maps.LatLng(/*lat, lng*/);
var myOptions = {
zoom: zoom,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: false,
panControl: false,
zoomControl: false,
scaleControl: false,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById("gmap"), myOptions);
map.mapTypes.set('ALTER_style', alterMapStyle);
map.setMapTypeId('ALTER_style');
}
function directions_init(){
directionsService = new google.maps.DirectionsService();
directionsDisplay = new google.maps.DirectionsRenderer();
directionsDisplay.setMap(map);
display_route();
}
function display_route(){
var request = {
origin: 'Place A',
destination:'Place B',
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
//program got here without error
directionsDisplay.setDirections(result);
}
});
}
Not sure if it's the source of your problems, but it's sure worth a shot...
From your script input
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?key=AIzaSyAB2gbXmG... ...mNs66iPr8&sensor=false&callback=directions_init"></script>
I assume the directions_init function is called after api script has been downloaded, which probably is before page's onload event, thus your map object has not been initiated and is null. So practically you are calling
directionsDisplay.setMap(null);
Try calling directions_init from gmap_init or on any event that is triggered after onload.

Categories

Resources