Using Google maps v3 API. When i visit the page with the map i sometimes get following error : "custom.js:46 Uncaught ReferenceError: google is not defined".
API's enabled on the key:
Google Maps Directions API
Google Maps Distance Matrix API
Google Maps Elevation API
Google Maps Geocoding API
Google Maps JavaScript API
When i reload the page, everything is working fine. This doesn't work 100% of the time. Multiple reloads are needed on some occasions.
I did notice that when the map isn't loading correctly this script is running in my head tags:
<script type="text/javascript" charset="UTF-8" src="https://maps.googleapis.com/maps/api/js/AuthenticationService.Authenticate?1shttp%3A%2F%2Fmayan-co.com%2Fen%2Foutlets&MYKEY&callback=_xdc_._h7cv8d&token=60166"></script>
After 10-20 seconds this script goes away and when i refresh the page after this script goes away, my map is working correctly.
Things i tried without results:
Putting the script to load the API in the footer.
Not using async or defer.
Adding specific url's to my api key.
Not using a api key
Loading the api script in the Head of my page:
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY" async defer></script>
My script to render the map and place markers on the map (loaded in the footer)
jQuery(document).ready(function($) {
$('#animation').addClass('animate');
$('.heart img').popover({
placement: 'top',
html: true,
container: '#animation',
content: function () {
return $(this).attr('alt');
}
});
$('body').on('click', function(e) {
$('.heart img').each(function() {
if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.heart img').has(e.target).length === 0) {
$(this).popover('hide');
} else {
$(this).popover('toggle');
}
});
});
function render_map($el) {
var $markers = $(document).find('#locations .data-source li');
var args = {
zoom: 16,
center: new google.maps.LatLng(0, 0),
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false,
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP]
}
};
var map = new google.maps.Map($el[0], args);
map.markers = [];
index = 0;
$markers.each(function() {
add_marker($(this), map, index);
index++;
});
center_map(map);
}
function add_marker($marker, map, index) {
var latlng = new google.maps.LatLng($marker.attr('data-lat'), $marker.attr('data-lng'));
var image = '../../img/maps-leaf.png';
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: image
});
map.markers.push(marker);
if ($marker.html()) {
$('#locations .data-display').append('<li class="linkage" id="p'+index+'">'+$marker.html()+'</li>');
$(document).on('click', '#p' + index, function() {
infowindow.open(map, marker);
setTimeout(function() { infowindow.close(); }, 5000);
});
var infowindow = new google.maps.InfoWindow({
content: $marker.html(),
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
function center_map(map) {
var bounds = new google.maps.LatLngBounds();
$.each( map.markers, function( i, marker ){
var latlng = new google.maps.LatLng( marker.position.lat(), marker.position.lng() );
bounds.extend( latlng );
});
if( map.markers.length == 1 ) {
map.setCenter( bounds.getCenter() );
map.setZoom( 16 );
} else {
map.fitBounds( bounds );
}
}
$(document).ready(function(){
$('#map').each(function(){
render_map( $(this) );
});
});
});
What you describe looks like you try to instantiate the map before the Google Maps API JavaScript is loaded (you're using async attribute there). That's why it sometimes throws google is not defined error.
In other words, document.ready is called before https://maps.googleapis.com/maps/api/js?key=MYKEY is loaded.
Google Maps API allows you to use callback parameter in the URL with a name of a function that's called after the API is fully loaded. See https://developers.google.com/maps/documentation/javascript/tutorial.
So in your case you'll use URL like:
https://maps.googleapis.com/maps/api/js?key=MYKEY&callback=initMap
And then initialize the map:
initMap() {
var map = new google.maps.Map($el[0], args);
}
Related
I need to use the location a marker is placed to be able to load weather data via another API. I have my map dropping a loading and dropping a marker as well as a object "myPosition" which should contain the lat and lon of the marker. My issue is getting the myPosition.lat and .lng to update with the coordinates of the marker. Below is the code I have thus far and I am able to get the initialized data from myPosition in another file but I cant figure out how to get the coordinates. This is my first time using HTML and JS and I usually use C++ or Java so its a bit of a change for me.
var myPosition =
{
lat: 0,
lng: 0
};
function initMap()
{
var texas = {lat: 32.7767, lng: -96.7970};
var map = new google.maps.Map(document.getElementById('map'),
{
zoom: 10,
center: texas
});
var marker = new google.maps.Marker({
position: texas,
map: map
});
google.maps.event.addListener(map, 'click', function(event)
{
placeMarker(event.latLng);
});
function placeMarker(location)
{
if (marker == undefined)
{
marker = new google.maps.Marker(
{
position: location,
map: map,
animation: google.maps.Animation.DROP,
});
}
else
{
marker.setPosition(location);
}
map.setCenter(location);
}
}
Sounds like what you need is to think about the problem less as your 'other file' accessing the coordinates, and more as notifying your other module that a mouse click on the map has occurred by means of a callback.
Eg. In weather.js
function handleCoords(latlng){
//...Do whatever you want with latlng
}
// Export function as needed if you're using modules/webpack.
// (don't worry if you don't know what this means)
Then in your main.js in your embedded HTML embedded JS
// import {handleCoords} from './weather'
// Again ignore this if you're not using modules/don't know what this means.
google.maps.event.addListener(map, 'click', function(event){
placeMarker(event.latLng);
handleCoords(event.latLng); // This is how you pass the latlng
// along to weather.js
});
I am trying to connect to the Google Maps API from a localhost through an AngularJS application but the map does not appear and the map request does not reach google. The javascript file is being found by the html, and test1 is being outputted in the console, but initMap is not being called and test2 is not outputted. I expect that it is failing because a https connection is not being made to Google.
When I open the html file in a browser, the map loads fine but when I run it on my localhost, nothing comes up.
Here is my html code:
<script src="client/services/maps.client.services.map.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key={{API_KEY}}&callback=initMap"></script>
and javascript (map.js):
console.log('test1');
function initMap() {
console.log('test2');
//Markers
var markers = [
['Cardiff', 51.4539, -3.1694, 'city/cardiff'],
['Swansea', 51.6148, -3.92927895, 'city/swansea']
];
// Initialise map
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: {lat: 51.4539, lng: -3.1694}
});
var bounds = new google.maps.LatLngBounds();
for( i = 0; i < markers.length; i++ ) {
// Plot pin for each place
var position = new google.maps.LatLng(markers[i][1], markers[i][2]);
bounds.extend(position);
marker = new google.maps.Marker({
position: position,
map: map,
title: markers[i][0]
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
window.location.href = markers[i][3];
}
})(marker, i));
}
// Zoom so all pins are in view
map.fitBounds(bounds);
}
Does anyone understand why the initMap function is not being called?
change the order of the script tags
<script src="https://maps.googleapis.com/maps/api/js?key={{API_KEY}}&callback=initMap"></script>
<script src="client/services/maps.client.services.map.js"></script>
First of all, I just started with JavaScript, so I'm not really good at it. I am making an app, using the Google Maps Places API, in which you can push a button and get your location, push another button and get nearby places (for example stores or bars) based on your location. Getting the location of the device works, but my code doesn't display the nearby places. It does go to the location, but it doesn't show the markers of the nearby places. I don't know what is going wrong, but I think it might have to do with the code for the markers or with the sequence of the code.
I am using Intel XDK (HTML5 + Cordova and the App Designer) and the Google Maps Places API. Right now it all happens when one button (with id="myloc-btn") is pushed, but (if both the location and the nearby places work) I want to seperate them in two buttons, one to show the location and one to show the nearby places.
Below is my javascript code. I have commented out the marker for the location of the device I originally had, because I thought it might be in the way of the markers for the nearby places.
Anyone know what's wrong or can help me?
Thanks in advance!
---UPDATE---
I tried the search nearby places from the Google Maps documentation (https://developers.google.com/maps/documentation/javascript/examples/place-search), with a set location (I basically copied and pasted the code), but that doesn't work either. Again it goes to the right location, but it doesn't display any markers. I tried it both in the simulator and on my phone, but it both has the same result. I don't know why the markers don't show
var map;
var service;
var infoWindow;
var pos;
var marker = [];
//var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
//var labelIndex = 0;
function register_event_handlers() {
$(document).on("click", "#myloc-btn", function(evt) {
initMap();
});
function initMap() {
map = new google.maps.Map(document.getElementById('gmap'), {zoom: 14});
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
//addMarker(pos, map);
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
var request = {
location: pos,
radius: 5000,
type: ['store']
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
}
/*
function addMarker(location, map) {
var marker = new google.maps.Marker({
map: map,
// Define the place with a location, a query string and a label.
place: {
location: location,
query: 'This is my location'
},
label: labels[labelIndex++ % labels.length],
});
// Construct a new InfoWindow.
var infoWindow = new google.maps.InfoWindow({
content: 'Here I am!'
});
// Opens the InfoWindow when marker is clicked.
marker.addListener('click', function() {
infoWindow.open(map, marker);
});
}
*/
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
document.addEventListener("app.Ready", register_event_handlers, false);
})();
In the callback provided to getCurrentPosition(), you're setting pos. However, this callback will get called after the phone has determined the location, i.e. at some random point in the future. Which is long after you're trying to use that pos in your request for the places. You need to move the places code in its own function, then call it while passing the map and pos, after you have centered the map. Almost exactly what you already did with addMarker().
I am building a search form using Google Maps Javascript V3 API. I would like to add some filters that will hide certain types of markers on the map when clicked. The markers to hide are represented with
locations[i][11] == 'Other'
HTML:
Hide Other Markers
JavaScript:
var geocoder;
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: { lat: 48.509532, lng: -122.643852}
};
var map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions);
var locations = <?php echo json_encode($locations_array); ?>;
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
animation: google.maps.Animation.DROP,
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
var content = '';
infowindow.setContent(content);
infowindow.open(map, marker);
}
})(marker, i));
google.maps.event.addDomListener(document.getElementsByClassName('hideOtherMarkers')[0], 'click', function() {
if (locations[i][11] == 'Other') {
marker.setVisible(false); // maps API hide call
}
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
When I click the link nothing fires, verified with alerts. I also tried google.maps.event.addListener (without Dom) with no success.
As commented by geocodezip this approach will not work, because i will always point behind the end of locations. Additionally this would hide at best 1 marker (the last marker that has been created).
Possible approach:
Store the visible-state of the markers in a MVCObject:
map-options:
var mapOptions = {
center: { lat: 48.509532, lng: -122.643852}
//that's the property where we store the state
visibility:new google.maps.MVCObject
};
inside the loop, after the creation of marker:
//when the state is not set yet, set it
if(typeof map.get('visibility').get(locations[i][11])==='undefined'){
map.get('visibility').set(locations[i][11],true);
}
//bind the visible-property of the marker to the state
marker.bindTo('visible',map.get('visibility'),locations[i][11]);
add the listener(outside of the loop):
google.maps.event.addDomListener(
document.getElementsByClassName('hideOtherMarkers')[0],
'click',
function() {
//simply set the desired property of the MVCObject to false
map.get('visibility').set('Other',false);
});
Demo: http://jsfiddle.net/doktormolle/5L2392mL/
I have a set of jQuery UI tabs that each load project.php using ajax. Depending on the parameters passed to the script, a different Google map is displayed using the following JavaScript inside project.php:
var tab_index = $('#tabs').tabs('option', 'selected');
$('.site_map:visible').css('height','300px');
MapID = $('.site_map:visible').attr('id');
if (MapID !== 'map-new'){
var map_id = 'map-'+tab_index;
$('.site_map:visible').attr('id', map_id);
} else {
MapNewSite();
}
var latlng = new google.maps.LatLng(19,-70.4);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
arrMaps[tab_index] = new google.maps.Map(document.getElementById("map-" + tab_index), myOptions);
arrInfoWindows[tab_index] = new google.maps.InfoWindow();
placeMarker($('.site_details:visible .inpLat').val(), $('.site_details:visible .inpLng').val(), tab_index);
function MapNewSite(){
arrMaps[tab_index] = new google.maps.Map(document.getElementById("map-new"), myOptions);
placeMarker(19,-70.4,tab_index);
arrInfoWindows[tab_index] = new google.maps.InfoWindow();
}
Each map loaded using parameters returned by a query of my database loads without any problems. However, in one last instance, I load project.php in a tab without any parameters so as to have a blank tab for users to manipulate. The signal that the map is not to be loaded using database coordinates is that the id of its div is "map-new".
The map generated in this tab loads, but then gives me the "a is null" error which usually means it couldn't find a div with the id specified to initialize the map. What is causing this error even after the map has loaded? How do I stop the error from occurring?
Here is the JavaScript in the parent page containing the tab site:
var arrMaps = {};
var arrInfoWindows = {};
var arrMarkers = {};
function placeMarker(lat, lng, tab_index){
map = arrMaps[tab_index];
var bounds = new google.maps.LatLngBounds();
var latlng = new google.maps.LatLng(
parseFloat(lat),
parseFloat(lng)
);
bounds.extend(latlng);
createMarker(latlng, tab_index);
map.fitBounds(bounds);
zoomChangeBoundsListener =
google.maps.event.addListener(map, 'bounds_changed', function(event) {
if (this.getZoom()){
this.setZoom(10);
}
google.maps.event.removeListener(zoomChangeBoundsListener);
});
}
function createMarker(latlng, tab_index) {
var html = 'Click here to move marker';
arrMarkers[tab_index] = new google.maps.Marker({
map: arrMaps[tab_index],
position: latlng
});
arrInfoWindows[tab_index] = new google.maps.InfoWindow();
google.maps.event.addListener(arrMarkers[tab_index], 'click', function() {
arrInfoWindows[tab_index].setContent(html);
arrInfoWindows[tab_index].open(arrMaps[tab_index], arrMarkers[tab_index]);
});
}
$(function() {
$( "#tabs" ).tabs({
ajaxOptions: {
error: function( xhr, status, index, anchor ) {
$( anchor.hash ).html(
"Couldn't load this tab. We'll try to fix this as soon as possible. " +
"If this wouldn't be a demo." );
}
},
cache: true
});
});
Take a look to http://www.pittss.lv/jquery/gomap/. Easy to use and very powerful. I myself use it.
It turns out I was accidentally initializing the map both inside the if and outside of it.