How do I prevent Google Maps from reinitializing after a geocode lookup? - javascript

I'm using the Google Maps Javascript API v.3. Below is the javascript that I've written. The goal is to initialize a map, and then do an address lookup via the Google maps geocoder, use that lat long to re-center the map, and set a marker down. I think I've got most of it working, except that after I recenter the map and place a marker, the page fires another onLoad event which causes the initialize() function to run again and resets all of my variables. After staring at this code for half a day, I'm not sure what is causing the extra onLoad event. What is causing it?
I am also new to writing javascript and working with Google maps, so I'm happy for other pointers on code quality. I know that I've tried to scope several variables globally and I'm not sure that I've done it correctly.
Here is the code (note: I plan on replacing the setTimeout function eventually, but I still haven't gotten the knack of programming asynch calls yet...I figured I will tackle that next).
<script type="text/javascript">
var map;
var geocoder;
var marker;
var latlng;
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(47.606, -122.314),
zoom: 12
};
if (this.map == null){
this.map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
}
function checkResponse(results, response){
if (response == google.maps.GeocoderStatus.OK) {
this.latlng = results[0].geometry.location;
this.map.setCenter(results[0].geometry.location);
this.marker = new google.maps.marker({ map: map, position: results[0].geometry.location});
}
else {
alert("Geocode was not successful for the following reason: " + response);
}
}
function searchAddress(){
var address = document.getElementById('address1').value;
var state = document.getElementById('state1').value;
var zip = document.getElementById('zip1').value;
var addressInput = address + ',' + state + ',' + zip;
geocoder.geocode( { 'address': addressInput}, function(results, status) {
//ToDo remove this setTimeout function and replace it with a callback
setTimeout(checkResponse(results, status), 3000);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>

When using a javascript function as the onsubmit function for a form, you must return false from the function if you don't want the page reloaded from the server.

Related

Google Map infowindow showing last value of loop

I have used for loop to display the markers and info window. But the infowindow showing only the last value of the loop.
Here is the code im using.
function initialize()
{
try
{
var geocoder;
var map;
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(41.511770, -72.809520);
var mapOptions = {
center: latlng,
zoom: 9,
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var markers = JSON.parse('[{"address":"40C Leslie Road,Bridgeport,CT","Description":"Bridgeport - 82 Unit Community"},{"address":"56 Ironwood Road,West Hartford,CT","Description":"West Hartford - 45 Unit Community"}]');
var infoWindow = new google.maps.InfoWindow();
// var address;
for (i = 0; i < markers.length; i++)
{
var address = markers[i];
geocoder.geocode({ 'address': address.address }, function (results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
//map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
icon:'Images/pin.png',
position: results[0].geometry.location
});
google.maps.event.addListener(marker, "click", function (e)
{
infoWindow.setContent("<div style='border:0px solid red;height:auto;;width:auto;'>" + address.Description + "</div>");
infoWindow.open(map, marker);
});
}
else {
//alert("Geocode was not successful for the following reason: " + status);
}
});
// map.setCenter(new google.maps.LatLng(41.511770, -72.809520))
}
}
catch (ex)
{
alert(ex.message);
}
}
google.maps.event.addDomListener(window, "load", initialize);
Please help me.
Thanks,
Venkat.
The problem is that geocoder.geocode is an asynchronous function. In other words, your execution moves away from the for loop before your requests has finished retrieving the values. Thus, you will be getting same address values, because it is the last value of the for loop when it had finished and you are placing everything to the same var address = ... variable.
To fix this, you need to wrap your geocoder.geocode request inside a self-executing anonymous function. As a result, your code works properly, because var address = ... is defined in it's own scope, together with the requests. See example below:
...
// Start of self-executing anonymous function
(function() {
var address = markers[i];
...
and:
...
// End of self-executing anonymous function
})();
// map.setCenter(new google.maps.LatLng(41.511770, -72.809520))
...
JS FIDDLE EXAMPLE (Remember to activate your icon image, I disabled it in that code.)
For further reading, I recommend self executing anonymous functions.
Cheers.

How to pass a variable into a function defined in the argument of another function in JavaScript? [duplicate]

This question already has answers here:
Google Maps : Issue regarding marker icons and geocoding
(1 answer)
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
I am working on Google Maps API v3 javascript. I am using the Geocoder feature where I am passing a city name and plotting it on the map. Along with this marker, I want to add a separate info window for every marker but I am not able to do that. All the infowindows are displaying the content that was set for the last marker instead of setting a different info window for each. Please find the javascript code below:
function initialize() {
geocoder = new google.maps.Geocoder();
var address = document.getElementById('address').value;
var jString = JSON.parse(address);
var infowindow;
for (var key in jString) {
contentStr = JSON.stringify(jString[key]); //This is step where I am setting the content which is independent for every maker
if (jString.hasOwnProperty(key)) {
geocoder.geocode( { 'address': key}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
infowindow = new google.maps.InfoWindow({
content: contentStr//Not able to access 'contentStr' set above.
});
infowindow.open(map,marker);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
}
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 8,
center: latlng
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
After debugging I understood that for some reason, the value of the variable 'contentStr' being set during the last iteration of 'for' loop is only being used for all the below function calls made:
geocoder.geocode( { 'address': key}, function(results, status) {
So basically, I am not able to pass the variable 'contentStr' into the function defined in the argument of another function. I think I am missing something basic here. Could anyone please guide me about this?
Thank you!
I have had the same problem many times. Stolen from link below. You need to attach the infowindow to your marker.
Marker content (infoWindow) Google Maps
function createMarker(lat, lon, html) {
var newmarker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lon),
map: map,
title: html
});
newmarker['infowindow'] = new google.maps.InfoWindow({
content: html
});
google.maps.event.addListener(newmarker, 'mouseover', function() {
this['infowindow'].open(map, this);
});
}
A second way of doing this. :
Google Maps API V3 infoWindow - All infoWindows displaying same content

Adding a google map to my site

I want to add a map to my site to show a local business, but I don't want to use an image, I wanted to use google maps like I have seen on some websites.
I tried using this:
https://developers.google.com/maps/documentation/javascript/reference#MapOptions
But it doesn't work (do you need to have it up on a server to work? I am just testing it local at the moment)
EDIT: Works now, I don't know what I did but it works.
there are few things you need to add ADD LAT, ADD LONG and ADD YOUR ADDRESS HERE
<div id="map-canvas" style="height:300px;"></div>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true"></script></script>
<script>
jQuery(document).ready(function($){
codeAddress();
});
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(ADD LAT, ADD LONG);
var mapOptions = {
zoom: 14,
center: latlng
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function codeAddress() {
geocoder.geocode( { 'address': 'ADD YOUR ADDRESS HERE'}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize());
</script>
If you just want to create a map to show where is your business as most the websites the answer is much simpler.
1 - Go to Google maps website and search for the address you want to add.
2 - Once you find the address in the button right of the screen click in settings
3 - Select share a embedded map.
4 - Select the size of the map and you will get something like this on the bar in the side
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3192.61190945592!2d174.74475940000002!3d-36.85176959999998!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x6d0d4793eebb1d67%3A0x6830f22a202256c9!2sPonsonby+Rd!5e0!3m2!1sen!2snz!4v1393896861642" width="400" height="300" frameborder="0" style="border:0"></iframe>
Put into your website and job done :)

Loading markers at intervals

In my project I have a google map, and I need to get markers on my map from database.
I have simple code like in example:
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 8,
center: latlng
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function codeAddress() {
var address = document.getElementById('address').value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
google.maps.event.addListener(map, 'idle', function () {
getmarkers(map);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
This code works well, but it has one lack - it loads new markers only if user moves map.
But I need to load markers also if user is just sitting in front of computer and look on a map, not moving it.
I think the best way to do this is to use setInterval(getmarkers(map), 3000) but if I use it except where that function google.maps.event.addListener(... it can't find map. Are there any ways to solve this problem?
there are 2 issues,
setInterval expects the first argument to be a function(but it isn't, it's a function-call which will be executed immediately). Use a anonymous function to execute the statement:
setInterval(function(){getmarkers(map);}, 3000);
place the setInterval-call at the end of initialize to be sure that map is defined.

Noob question: How to get information if google map is loaded (initialized)

I am new with google maps api. I took some sample from the manual and trying to change it the way I need, so here is the what I am trying to do:
This is the example from google maps manual
var geocoder;
var map;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng( 40.714353, -74.005973);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
I have changed codeAddress function a little and trying to call it on page load like this:
function codeAddress(address) {
//var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
codeAddress("Some Address");
But it give me a javascript error "geocoder is undefined". How can I make the script wait until the map is loaded and then run the codeAddress function? I don't want to path my address during initialization.
I hope this is clear
Thank you in advance.
The problem is that you're calling codeAddress directly after defining it (and hence this is before the initialise() method runs.
Consequently you need to run this later on some trigger. A quick and dirty way to do this is to set this as the body's onload event; this will wait until all resources (including images) have fully loaded, but that might not be too much of a problem given that the map is an image as well.
Alternatively, most JS frameworks will give you very convenient methods to fire your handlers at various points in the page's lifecycle. If you're using one of these, you may wish to investigate the options available to you and pick the best one, which depends on a number of factors.
Critically, don't forget that you must call initialise() before you call codeAddress()!

Categories