I am dynamically loading content into a page and one of the pages has a google map point. Everything works fine except map point doesn't show up. Map api is loaded asynchronously so if I understand it correct it should work.
Example taken from official google's documentation
<script>
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
function loadScript() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&' +
'callback=initialize';
document.body.appendChild(script);
}
</script>
<div class="joomsport-event-location">
<div class="map" id="map-canvas" style="height: 50%"></div>
<script>
loadScript();
alert('loading'); // test if it's called
</script>
</div>
This is source that is loaded into another page using jQuery. And once loaded I get expected alert. Am I missing something ? Or it's not even possible what I am trying to do?
Related
How is it possible to use the Google Maps API with AngularJS?
I am using this code in my AngularJS app:
<style>
#googleMap {
width: 200px;
height: 200px;
}
</style>
<div id="googleMap"></div>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js"></script>
<script language="javascript">
var map;
function initialize() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644)
};
map = new google.maps.Map(document.getElementById('googleMap'), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
This code is in the view and not in the controller.
I have other functions in the view and they work, but google map is still not working.
This is the error I get in the browser console:
Error: google is not defined
#http://localhost:3000/js/jquery-1.11.2.min.js line 2 > eval:10:2
.globalEval/<#http://localhost:3000/js/jquery-1.11.2.min.js:2:2615
.globalEval#http://localhost:3000/js/jquery-1.11.2.min.js:2:2589
.domManip#http://localhost:3000/js/jquery-1.11.2.min.js:3:23105
.after#http://localhost:3000/js/jquery-1.11.2.min.js:3:21067
Cehttp://localhost:3000/js/angular/lib/angular.min.js:176:70
n#http://localhost:3000/js/angular/lib/angular-route-segment.min.js:7:5868
.compile/http://localhost:3000/js/angular/lib/angular-route-segment.min.js:7:6428
Pe/this.$gethttp://localhost:3000/js/angular/lib/angular.min.js:128:120
p#http://localhost:3000/js/angular/lib/angular-route-segment.min.js:7:2649
this.$gethttp://localhost:3000/js/angular/lib/angular-route-segment.min.js:7:3989
f/<#http://localhost:3000/js/angular/lib/angular.min.js:112:20
Pe/this.$gethttp://localhost:3000/js/angular/lib/angular.min.js:125:301
Pe/this.$gethttp://localhost:3000/js/angular/lib/angular.min.js:122:390
Pe/this.$gethttp://localhost:3000/js/angular/lib/angular.min.js:126:56
l#http://localhost:3000/js/angular/lib/angular.min.js:81:169
S#http://localhost:3000/js/angular/lib/angular.min.js:85:301
vf/http://localhost:3000/js/angular/lib/angular.min.js:86:315
What am I doing wrong?
I searched the web but everyone seems to be using libraries like angular-google-map or ui-map. Why is no one using the direct API?
You can implement google maps in angularjs without using any plugins like this,
<!--use this div where ever you want to create a map-->
<div id="map"></div>
define the width and height for map div,
#map {
height:420px;
width:600px;
}
in controller you glue this id="map" with scope like this,
$scope.mapOptions = {
zoom: 4,
center: new google.maps.LatLng(41.923, 12.513),
mapTypeId: google.maps.MapTypeId.TERRAIN
}
$scope.map = new google.maps.Map(document.getElementById('map'), $scope.mapOptions);
if you want to create markers for the cities or countries you want,
var cities = "Atlanta, USA";
var geocoder= new google.maps.Geocoder();
$scope.markers = [];
var createMarker = function (info){
var marker = new google.maps.Marker({
map: $scope.map,
position: new google.maps.LatLng(info.lat(), info.lng())
});
}
geocoder.geocode( { 'address': cities }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
newAddress = results[0].geometry.location;
$scope.map.setCenter(newAddress);
createMarker(newAddress)
}
});
Last but not least make sure you added the google maps api script before doing all this stuff,
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"> </script>
Here is the working plunker with this code, inside a bootstrap model,
http://embed.plnkr.co/VT7cO0L2ckSWG6g63TVG/preview
Reference
Hope this helps!
It was late to post but I have done this as solution. By this there is no need to add the google map script src in the head of the html or there is no chance of any error for google map src related errors. The script will be added automatically by the loadScript function. In angular it is needed to add new js src in partials rather than the head of main script. So I think this will be the best solution
I used this code chunk into my controller.
$scope.initialize = function() {
$scope.mapOptions = {
zoom: 8,
center: new google.maps.LatLng(22.649907498685803, 88.36255413913727)
};
$scope.map = new google.maps.Map(document.getElementById('googleMap'), $scope.mapOptions);
}
$scope.loadScript = function() {
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.google.com/maps/api/js?sensor=false&callback=initialize';
document.body.appendChild(script);
setTimeout(function() {
$scope.initialize();
}, 500);
}
setTimeout is there because some time is needed for google map src to be downloaded and be ready. & callback=initialize is needed because by this google map will be ready for a callback.The main problem was that the code google.maps.event.addDomListener(window, 'load', initialize) was not executing if I add the google map src in partial rather than the head of main index.html. But this setup works flawlessly.
And this chunk to the html
<div class="form-group col-lg-12" id="googleMap">
<center>Waiting for the map...</center>
</div>
Now place ng-init="loadScript()" anywhere in any outer div so that loadScript initializes before.
I'm receiving the following error in the console when loading Google Maps asynchronously in a Rails App using Turbolinks (not sure if turobolinks is related to the error). The map loads as expected, but I can't seem to clear this error.
Uncaught SecurityError: Blocked a frame with origin
"https://www.google.com" from accessing a frame with origin
"https://example.com". Protocols, domains, and ports must match.
The initialization script is very similar to the vanilla example in the API docs, except that the loadScript function is triggered on the turbolinks page:load event.
function initialize() {
var lat = $('#map-canvas').data('lat');
var long = $('#map-canvas').data('long');
var mapOptions = {
zoom: 14,
center: new google.maps.LatLng(lat, long),
mapTypeId: google.maps.MapTypeId.SATELLITE,
disableDefaultUI: true,
zoomControl: true
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
function loadScript() {
if ( $( "#map-canvas" ).length ) { //only initialize on map pages
if (typeof google == "undefined") { //prevent duplicate loading
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp' +
'&signed_in=true&callback=initialize';
document.body.appendChild(script);
}else{
initialize();
}
}
}
$(document).on("ready page:load", loadScript);
I've done a lot of searching for this issue, and found a lot of results but none that seem to help in this case. I setup a google map a while ago and it worked. Then with out me changing anything it stopped working in chrome & opera, but still worked in IE and chrome for android. The other day I replaced it with fresh code and got it working again in all browsers, but now I notice it is no longer working in chrome & opera, but works fine in IE and chrome for android. What the devil is going on?
<div id="map-canvas" style="width:100%; height:300px; max-width: 100%;"></div>
<script type="text/javascript">
function initialize() {
var myLatlng = new google.maps.LatLng(<? echo $lat; ?>, <? echo $long; ?>);
var mapOptions = {
zoom: 15,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "Hello world"
});
//marker.setMap(map);
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://maps.googleapis.com/maps/api/js?key=API_KEY_HERE&sensor=false&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
I will add that I am using twitter bootstrap 2.x on this project in case that has a bearing.
This was an issue with Cloudflare's Rocket Loader. I'm awaiting a fix from CF.
I have searched a lot of solutions for this problem but none worked out for me. I would like to integrate Google Maps into a Wordpress page, without using a plugin and without embedding.
In the head of header.php I attached this:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=*********&sensor=true"> </script>
Then also in header.php I have put this:
<body onload="initialize()">
But now I don't know where to put the script:
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(50.371, -4.136),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyDo2uLLlKn3xuYolvd0VNzBujoZ952YywE&sensor=true&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
If anybody has a solution I would really appreciate it, thanks a lot!
You can put the code into a js file and load it after the api script include.
A little bit cleaner code would be:
(function () {
function initMap() {
var mapOptions = {
center: new google.maps.LatLng(50.371, -4.136),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initMap);
}());
With this self calling anonymous function you don't introduce globals and encapsulates you code.
For my project i need google maps api.
I just can serve the api via script tag, so i tried something like that.
my html:
<head>
<title>app</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script>
</head>
<body>
{{> hello}}
</body>
<template name="hello">
<div id="map-canvas"/>
</template>
my js:
if (Meteor.isClient) {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}
On execution the error is:
Uncaught ReferenceError: google is not defined
How can i get this working?
The meteor script is typically run before the google maps API is loaded so its best to put your code in a Template.rendered : see Template.rendered at the meteor docs
e.g If you have a template
<template name="maps">
<div id="map-canvas"></div>
</template>
Your js would be:
Template.maps.rendered = function() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
}
It really depends more on what your template looks like. The rendered callback will re run everytime the template changes reactively too. So if you find it re-renders you might have to use a Session hash to check it only sets the maps center/settings only once.
Another option would be to put your map centering code in Meteor.startup(function() { ... });, but again this depends on your template structure as the map needs to be visible on the first template and not one another page (as the div element wont be on the screen)