Google map on page loaded by AJAX - how to initialize? - javascript

I'm having a bit of trouble getting a google map to initialize on a page loaded by AJAX.
Live test page (in dev): http://dma.nz/practice/
The map is near the bottom of the page.
Currently it works - the map initializes when page it loaded directly or via AJAX, however it's giving me the following error in console:
Uncaught TypeError: Cannot read property 'firstChild' of null
In my footer I have:
<script src="/js/map.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBpC5JE9ZmQduEXiGbiNxZsws8OLMiC-Bw&callback=initMap" async defer></script>
<script src="/js/init.js"></script>
map.js contains:
function initMap() {
var mapOptions = {
zoom: 17,
center: new google.maps.LatLng(-36.85855, 174.754944),
disableDefaultUI: true,
styles: [
{"featureType":"administrative",
"elementType":"labels.text.fill",
"stylers":[{"gamma":"0.00"},{"weight":"0.01"},{"visibility":"off"}]
},
{"featureType":"landscape",
"elementType":"all",
"stylers":[{"color":"#ffffff"}]
},
{"featureType":"landscape.natural",
"elementType":"geometry",
"stylers":[{"visibility":"on"}]
},
{"featureType":"landscape.natural.terrain",
"elementType":"geometry.stroke",
"stylers":[{"visibility":"on"}]
},
{"featureType":"poi",
"elementType":"all",
"stylers":[{"visibility":"off"}]
},
{"featureType":"road",
"elementType":"all",
"stylers":[{"saturation":"-100"},{"lightness":"32"},{"visibility":"on"}]
},
{"featureType":"road",
"elementType":"labels.text",
"stylers":[{"visibility":"off"}]
},
{"featureType":"road.highway",
"elementType":"all",
"stylers":[{"visibility":"simplified"}]
},
{"featureType":"road.highway",
"elementType":"geometry",
"stylers":[{"visibility":"on"},{"lightness":"63"}]
},
{"featureType":"road.highway",
"elementType":"labels.text",
"stylers":[{"visibility":"off"}]
},
{"featureType":"road.highway",
"elementType":"labels.icon",
"stylers":[{"visibility":"off"}]
},
{"featureType":"road.arterial",
"elementType":"labels.icon",
"stylers":[{"visibility":"off"}]
},
{"featureType":"transit",
"elementType":"all",
"stylers":[{"visibility":"off"}]
},
{"featureType":"transit.station",
"elementType":"all",
"stylers":[{"visibility":"off"}]
},
{"featureType":"water",
"elementType":"all",
"stylers":[{"visibility":"on"},{"color":"#eeeeee"}]
}
]
};
// Get the HTML DOM element that will contain your map
var mapElement = document.getElementById('google-map');
// Create the Google Map using our element and options defined above
var map = new google.maps.Map(mapElement, mapOptions);
// Add marker
var marker = new google.maps.Marker({
icon: '/img/icons/map-pin.svg',
position: new google.maps.LatLng(-36.858749, 174.754944),
map: map,
title: 'DMA'
});
}
And then the related part of init.js
ajaxLoad = function(html) {
init();
// init google map
initMap();
// change html title
var HTMLtitle = $(".content > section:first-of-type").attr("data-title");
$(document).prop('title', HTMLtitle);
document.title = HTMLtitle;
// Used for popState event (back/forward browser buttons)
changedPage = true; }
The callback on my google maps API script call appears to properly initialize the map if page is loaded directly. If page is loaded by AJAX that doesn't work so I added the line initMap(); there to load the map after the new content is loaded via AJAX.
This is working, but throwing an error and I'm worried that this error is causing other script on my page not to work properly.
Any ideas on how to modify this so that the map initializes regardless of whether the page is loaded directly or by AJAX, and doesn't create any JS errors? Thanks!

I reproduced the error when I switched from the http://dma.nz/practice/ page to http://dma.nz/projects/ page.
As I can see you try to initialize map instance in line 82 of your map.js. The problem here is missing element with id "google-map". You don't have any DOM element with id "google-map" when you load the projects page. So you try to pass null in map constructor.
To avoid this error add a check that DOM element with id "google-map" exists.
// Get the HTML DOM element that will contain your map
var mapElement = document.getElementById('google-map');
if (mapElement) {
// Create the Google Map using our element and options defined above
var map = new google.maps.Map(mapElement, mapOptions);
// Add marker
var marker = new google.maps.Marker({
icon: '/img/icons/map-pin.svg',
position: new google.maps.LatLng(-36.858749, 174.754944),
map: map,
title: 'DMA'
});
}

Related

How to build a theme using jaredpalmer/presspack with Google Maps integration?

Introducing the problem
Building this theme using jaredpalmer/presspack for docker, I'm struggling for a few days now as I try to insert this pair of Google Maps instances within an element that will be called in every page. The maps won't load and Chrome tells me my function is not there.
Some context
Presspack is serving the DB and uses yarn to make a environment. It keeps scripts separately for general purposes and specific ones, as it has a common.js - where I code everything it should load on every page - and a .js - which loads only on specific pages. I'm working on common now, since I believe this contact section will be used on every page and blog post of this site. The calling function for this section is WP basic <?php get_template_part( 'content', 'contato-std' ); ?>
I've added a code in functions.php to load the API key script after the footer of my pages.
It's important to mention that I've tried the js code I'm using in common.js on another HTML only environment.
My files
common.js
export default {
init() {
// JavaScript to be fired on all pages
console.log('common');
},
finalize() {
// JavaScript to be fired on all pages, after page specific JS is fired
var isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile) { // Tudo o que for pra navegadores mobile
(...)
} else { // Tudo o que for pra navegadores padrão
(...)
// GOOGLE MAPS LOAD
var markers = [{
GPS1: -15.7954901,
GPS2: -47.8926766,
client_address: "Corpus - Fisioterapia & Pilates, Unidade Asa Sul"
}];
function initialize() {
initMap();
initMap2();
};
function initMap() {
var latlng = new google.maps.LatLng(-15.7954901, -47.8926766); // default location
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById('mapaAsaSul'), myOptions);
var infowindow = new google.maps.InfoWindow(),
marker, lat, lng;
for (i = 0; i < markers.length; i++) {
lat = (markers[i].GPS1);
lng = (markers[i].GPS2);
name = (markers[i].client_address);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
name: name,
map: map
});
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent(this.name);
infowindow.open(map, this);
}.bind(marker));
}
}
var markers2 = [{
GPS1: -15.7187167,
GPS2: -47.8867326,
client_address: "Corpus - Fisioterapia & Pilates, Unidade Lago norte"
}];
function initMap2() {
var latlng = new google.maps.LatLng(-15.7187167, -47.8867326); // default location
var myOptions = {
zoom: 16,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
mapTypeControl: true
};
var map = new google.maps.Map(document.getElementById('mapaLagoNorte'), myOptions);
var infowindow = new google.maps.InfoWindow(),
marker, lat, lng;
for (i = 0; i < markers2.length; i++) {
lat = (markers2[i].GPS1);
lng = (markers2[i].GPS2);
name = (markers2[i].client_address);
marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lng),
name: name,
map: map
});
google.maps.event.addListener(marker, 'click', function(e) {
infowindow.setContent(this.name);
infowindow.open(map, this);
}.bind(marker));
}
}
},
};
function.php
<?php
...
function add_google_maps() {
wp_enqueue_script(
'my-google-maps',
'http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize',
NULL,
NULL,
true
);
add_filter( 'script_loader_tag', function ( $tag, $handle ) {
if ( 'my-google-maps' !== $handle )
return $tag;
return str_replace( ' src', ' async defer src', $tag );
}, 10, 2 );
}
add_action('wp_enqueue_scripts', 'add_google_maps');
?>
The JS handling the routing from common.js and .js is index.js
import jQuery from 'jquery';
import './style.scss';
import Router from './util/Router';
import common from './routes/common';
import home from './routes/home';
/**
* Populate Router instance with DOM routes
* #type {Router} routes - An instance of our router
*/
const routes = new Router({
/** All pages */
common,
/** Home page */
home
/** About Us page, note the change from about-us to aboutUs. */
});
/** Load Events */
jQuery(document).ready(() => routes.loadEvents());
Bad response
It should load both instances of maps within the respective div's #mapaAsaSul and #mapaLagoNorte, but it won't and Chrome's console returns this:
(index):1
Uncaught (in promise) Xc {message: "initialize is not a function", name: "InvalidValueError", stack: "Error↵ at new Xc (http://maps.googleapis.com/ma…KEY&callback=initialize:125:107"}message: "initialize is not a function"name: "InvalidValueError"stack: "Error↵ at new Xc (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:56:227)↵ at Object._.Yc (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:56:337)↵ at Uh (http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:125:221)↵ at http://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize:125:107"__proto__: Error
Promise.then (async)
Vh # js?key=KEY&callback=initialize:125
google.maps.Load # js?key=KEY&callback=initialize:21
(anonymous) # js?key=KEY&callback=initialize:212
(anonymous) # js?key=KEY&callback=initialize:212
This initialize is written in common.js. The file is listed in console, red by webpack (which presspack uses).
I'm running this #localhost so won't be able to provide a link for this page.
And I'm sorry if I've done any mistakes formatting this post or provide wrong info. Not really experienced at creating posts here in stack. :(
Any thoughts and ideas on this problem will be most welcome.
Edit: corrected that mistake as Evan suggested in the comments, where the calling was for maps.google.com and not maps.googleapis.com
Edit2: As Evan kept helping me on the comment section, I've made some additions to my code as follows.
The callback function that was returning a problem in console, was removed and I replaced it as a new callback for initialize function that appears on common.js.
var markers = [{(...)}];
function initialize() {(...)};
function initMap() {(...)};
var markers = [{(...)}];
function initMap2() {(...)};
google.maps.event.addDomListener(window, 'load', initialize); //This is the new callback for my maps
This did solved something, since the first map appeared. Still, there was still some error which console would point at:
"Uncaught ReferenceError: i is not defined at initMap (common.js?a395:77) at initialize (common.js?a395:56)" pointing at this line of common.js: for (i = 0; i < markers.length; i++) {.
I didn't get it. Just guessed that it had something to do with my markers code, since the first map appeared after the callback being made in common.js but with no marker.
Then, Evan pointed that if i was initialized globally, that error made sense. So he suggested changing the code to for (let i = 0; i < markers.length; i++) {, which did it for me. Adding it to both instances of markers in the code, made both maps appear properly and with markers.
Thanks for your help, Evan!
First of all, the JavaScript API should be called via https://maps.googleapis.com/, not http://maps.google.com/.
The "initialize is not a function" scope error can be worked around by loading the Maps API script synchronously on page load, e.g. by using google.maps.event.addDomListener(window, 'load', initialize), but in general the recommended approach is to load the API asynchronously via a callback:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=KEY&callback=initialize"></script>
Then there's an issue with both markers loops, e.g. for (i = 0; i < markers.length; i++), as they're missing i initialization. Try using for (let i = 0; i < markers.length; i++).
You can find here a working jsbin that shows both your maps and markers loading successfully after the above code changes.

google map not loading properly

hi every one i am trying to implement google map with marker in my project for that i am using the following code.
in my html
<div id="googleMap" style="height: 243px;"></div>
then in script
<script>
$(function () {
var map;
google.maps.event.addDomListener(window, "load", function () {
var map = new google.maps.Map(document.getElementById("googleMap"), {
center: new google.maps.LatLng(12.896452, 77.595717),
zoom: 17,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infoWindow = new google.maps.InfoWindow();
function createMarker(options, html) {
var marker = new google.maps.Marker(options);
if (html) {
google.maps.event.addListener(marker, "click", function () {
infoWindow.setContent(html);
infoWindow.open(options.map, this);
});
}
return marker;
}
var marker0 = new google.maps.Marker({
position: new google.maps.LatLng(12.896452, 77.595717),
map: map,
label: {
text: "Kanti Industries",
color: "#9f1b1f",
fontSize: "15px",
fontWeight: "bold",
},
title: 'Kanti Industries',
animation: google.maps.Animation.DROP,
});
});
});
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=****" ></script>
Now the odd problem is that when i uploaded the files on the server, on my laptop the map gets loaded and everything works fine but when i open the same page on other device like from browser of my mobile or some other laptop it does not loads and i get "oops" error...
now i don't have access to other PC to inspect or see what is the error in console. i checked everything the API key is right, i changed a few things to check if i am writing the correct URL, i accessed it from chrome, IE and Firefox. Every browser on my PC loads the map, i also cleared cache and all.
Here is another link of different server where i am using same code but here it is working fine..
I resolved it by adding http restrictions in my api key. Actually the client was using http// and i was using https//.

Load Google Map in new window by appending a button

I'm trying to append a button to a page that when clicked will display my google map in a new page. I have a button that when clicked either gives an error or gives a blank page.
My code:
$('.content--body__wrapper').append('<button id="show-map" />')
$('.content--body__wrapper').append(`<script>
document.getElementById("show-map").addEventListener("click", function(){
var center = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: center
});
var marker = new google.maps.Marker({
position: center,
map: map,
});
})
</script>`);
$('.content--body__wrapper').append(`<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBcwtM8EBe7BE1NyPbU5SDYVYoBBtbtpTI&libraries=drawing" asyncdefer></script>`);
Error Code:
Edit: I took the callback out of the script source and I still don't get a page to load but I do have a lot less errors.
$('.content--body__wrapper').append('<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBcwtM8EBe7BE1NyPbU5SDYVYoBBtbtpTI&libraries=drawing&callback=initMap" async defer></script>');
In this line you say : when the API is loaded run the function called InitMap.
The problem is that this function is not definied in your js.
So remove this callback to use the documentReady event or remove documentReadyListener and create a function name initMap

Bing Map doesn't display when I add another parameter to my function

I am loading longitude and latitude from my database, I want to add an additional field for for my function and pass in other values from my database to show when I click on my pin, it works fine with just the latitude and longitude as the parameters for the function AddData(latitude,longitude) but as soon as I add another value like AddData(latitude,longitude,Zoo Name) my map no longer displays. I am unsure of what I am doing wrong and I apologise if this is a simple mistake but I am just getting use to javascript.
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null, infobox, dataLayer;
function GetMap() {
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById("myMap"),
{ credentials: "API Bing Key" });
dataLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(dataLayer);
var infoboxLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(infoboxLayer);
infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false, offset: new Microsoft.Maps.Point(0, 20) });
infoboxLayer.push(infobox);
#foreach (var item in Model)
{
#: AddData(#item.latitude,#item.longitude,#item.ZooName);
//till here
}
}
function AddData(latitude, longitude,ZooName) {
var pin = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(latitude, longitude));
pin.Title = latitude.toString();
pin.Description = latitude.toString();
Microsoft.Maps.Events.addHandler(pin, 'click', displayInfobox);
dataLayer.push(pin);
}
function displayInfobox(e) {
if (e.targetType == 'pushpin') {
infobox.setLocation(e.target.getLocation());
infobox.setOptions({ visible: true, title: e.target.Title, description: e.target.Description });
}
}
</script>
<body onload="GetMap();">
<div id='myMap'></div>
</body>
Adding an additional parameter to your function shouldn't cause the map to stop working. I suspect that an error is occurring when accessing the #item.ZooName value. I'm guessing that this is a string, it likely needs to be surrounded with quotes. You should see an error in the browsers console. As such, the error is likely preventing the code to load the map from firing and thus the map is never loaded.

map as div background - Google Maps API

I'm using for a while following javascript code to load google map as DIV background.
// When the window has finished loading create our google map below
google.maps.event.addDomListener(window, 'load', init);
function init() {
// Basic options for a simple Google Map
// For more options see: https://developers.google.com/maps/documentation/javascript/reference#MapOptions
var mapOptions = {
// How zoomed in you want the map to start at (always required)
zoom: 15,
// The latitude and longitude to center the map (always required)
center: new google.maps.LatLng(54.549047, 18.443433), // New York
// How you would like to style the map.
// This is where you would paste any style found on Snazzy Maps.
styles: [ { featureType:"all", elementType:"all", stylers:[ { invert_lightness:true }, { saturation:10 }, { lightness:30 }, { gamma:0.5 }, { hue:"#1C705B" } ] } ]
};
// Get the HTML DOM element that will contain your map
// We are using a div with id="map" seen below in the <body>
var mapElement = document.getElementById('map');
// Create the Google Map using out element and options defined above
var map = new google.maps.Map(mapElement, mapOptions);
}
works perfectly. But when I've tried to load there a marker which will point to my location, it crashes. Any ideas what will be the proper placement of such? I assume this is the proper code (which doesn't work..):
var myLatlng = new google.maps.LatLng(54.549047, 18.443433);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Hello World!'
});
thanks for the help!

Categories

Resources