So, what I need is very simple, I need to put markers in a map, I get the data from a JSON I built using PHP. I looked up all other questions(really) about Google Maps markers not showing up, and none of them worked for me. I can't find the flaw in my code.
The JSON is like this (but 58 items long), 'id' is unimportant:
[
{
"id": "2",
"lat": "-49.217290",
"lon": "-16.416160",
"tit": "Heinz",
"desc": "18 Machines"
},
{
"id": "3",
"lat": "-49.235455",
"lon": "-16.676926",
"tit": "Warehouse",
"desc": "10 Machines"
}
]
I'm new here, sorry if I do something wrong. My code is bellow:
<div id="map" class="height-400"></div>
<script>
var map;
var myLatLon = {lat: -16.398293, lng: -48.965098};
var markers = [];
$.ajax({
dataType:'json',
url: "contents/map_data.php",
success: function(data){
markers = data;
}
});
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: myLatLon,
zoom: 4,
//disableDefaultUI: true,
});
var i= 0;
$.each(markers, function(i, item) {
if(typeof item == 'object') {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(item.lat),parseFloat(item.lon)),
map: map,
title: item.titulo,
label: item.desc
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(item.desc);
infowindow.open(map, marker);
}
})(marker, i));
i=i+1;
}
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_SECRET_KEY&callback=initMap" async defer></script>
Markers variable is an empty array, cause the AJAX request has not returned yet. You should either move your code inside success callback or invoke it from success callback.
Try something like:
<div id="map" class="height-400"></div>
<script>
var map;
var myLatLon = {lat: -16.398293, lng: -48.965098};
var markers = [];
$.ajax({
dataType:'json',
url: "contents/map_data.php",
success: function(data){
markers = data;
initMap();
}
});
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: myLatLon,
zoom: 4,
//disableDefaultUI: true,
});
var i= 0;
$.each(markers, function(i, item) {
if(typeof item == 'object') {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(item.lat),parseFloat(item.lon)),
map: map,
title: item.titulo,
label: item.desc
});
marker.setMap(map);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(item.desc);
infowindow.open(map, marker);
}
})(marker, i));
i=i+1;
}
});
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_SECRET_KEY&callback=initMap" async defer></script>
Related
I have a problem with my google map, its not displaying any markers at all. The data for the markers comes from wordpress post and custom fields.
I did a console log for var locations and the data is passed to this point. Also did a console log for var j and I'm getting there undefined.
What could be the problem that the markers are not displayed?
<?php
$args = array('post_type'=> 'investments'); $the_query = new WP_Query( $args );
if ( have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();
$investmentsData[$row]['meta'] = get_post_meta( $post->ID, 'investments_location_details', true );
$investmentsData[$row]['investment'] = [
'id' => get_the_id(),
'title' => get_the_title(),
];
foreach ($investmentsData as $key => $value) {
$investment = $value['tabs'];
$meta = $value['meta'];
}
wp_localize_script('jquery-core', 'investmentsData', $investmentsData);
?>
<div id="map"></div>
<script type="text/javascript">
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 11,
center: new google.maps.LatLng(54.233985, 16.8903183),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
var locations = <?php echo json_encode($investmentsData) ?>;
var j = locations.length;
function initMap() {
for (i = 0; i < j; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(investmentsData[i].lat, investmentsData[i].lng),
map: map,
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(investmentsData[i].title);
infowindow.open(map, marker);
}
})(marker, i));
}
};
</script>
<?php
endwhile;
endif;
wp_reset_postdata();
wp_reset_query();
?>
UPDATE
The consol log for var locations is giving an object with
investment: {id: 192, title: "Post title"}
meta: {lat: "54.3765137", lng: "18.5707837"}
When I'm doing a console log of investmentsData[i].lat I get this Uncaught ReferenceError: investmentsData is not defined and for locations[i].lat I get this Uncaught TypeError: Cannot read property 'lat' of undefined
I'm inducing the API like this <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC5rsZHHAmzP_pOuHGKEUtarn2QideIyUM"></script>
Update from comment on answer
The locations variable is an object:
var locations = {"":{"meta":{"lat":"54.2427318","lng":"16.8870907"},"investment":{"id":386,"title":"Termoizolacja obiekt\u00f3w u\u017cyteczno\u015bci publicznej na terenie..."}}};
Issues with your code:
lat and lng are properties of the locations[i].meta object
title is a property of the locations[i].investment object
you aren't calling initMap
your map's center and zoom are set such that you can't see the marker.
proof of concept fiddle
update
per the information on your live page, locations is an object, not an array:
var locations = {"":{"meta":{"lat":"54.2427318","lng":"16.8870907"},"investment":{"id":386,"title":"Termoizolacja obiekt\u00f3w u\u017cyteczno\u015bci publicznej na terenie Gminy K\u0119pice"}}};
process that by using:
for (var obj in locations) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[obj].meta.lat, locations[obj].meta.lng),
map: map,
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[obj].investment.title);
infowindow.open(map, marker);
}
})(marker, i));
}
updated fiddle
code snippet:
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>
<script type="text/javascript">
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 7,
center: new google.maps.LatLng(54.233985, 16.8903183),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
var locations = {
"": {
"meta": {
"lat": "54.2427318",
"lng": "16.8870907"
},
"investment": {
"id": 386,
"title": "Termoizolacja obiekt\u00f3w u\u017cyteczno\u015bci publicznej na terenie Gminy K\u0119pice"
}
}
};
for (var obj in locations) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[obj].meta.lat, locations[obj].meta.lng),
map: map,
});
console.log("marker position:" + marker.getPosition().toUrlValue(6));
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[obj].investment.title);
infowindow.open(map, marker);
}
})(marker, i));
}
};
initMap();
</script>
Here is a working example. With appropriate function calls and demo data.
function initMap() {
var locations = [{
investment: {
id: 192,
title: "Post title 1"
},
meta: {
lat: "54.3765137",
lng: "18.5707837"
}
},
{
investment: {
id: 193,
title: "Post title 2"
},
meta: {
lat: "54",
lng: "18"
}
}
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: new google.maps.LatLng(54.233985, 16.8903183),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
var j = locations.length;
for (i = 0; i < j; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i].meta.lat, locations[i].meta.lng),
map: map,
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i].investment.title);
infowindow.open(map, marker);
}
})(marker, i));
}
}
initMap();
#map {
height: 200px;
}
<div id="map"></div>
<script src="https://maps.googleapis.com/maps/api/js"></script>
I am trying to get the infowindows to populate with the Zomato API data, but I keep getting the last item in the object. I have tried a for loop with a closure and the for loop with "let" instead of "var", but this is not helping. Any suggestions that could push me forward would be greatly appreciated.
var map;
var markers = [];
var cuisines, name, establishment, locality, menu, photos, rating, infoContent;
var locations = [
{name: 'The Pub at Ghirardelli Square', latlng: {lat: 37.8063722222, lng: -122.4228888889}},
{name: 'The Irish Bank', latlng: {lat: 37.7902750000, lng: -122.4048472222}},
{name: 'Rogue San Francisco Public House', latlng: {lat: 37.8001440000, lng: -122.4104550000}},
{name: 'Chieftain Irish Restaurant & Pub', latlng: {lat: 37.7814900000, lng: -122.4051510000}},
{name: 'Kennedy\'s Irish Pub and Curry House', latlng: {lat: 37.8042510000, lng: -122.4156040000}},
{name: 'Murphy\'s Pub', latlng: {lat: 37.7901916667, lng: -122.4038472222}}
];
//create instance of a map from the Google Maps API
//Grab the reference to the "map" id to display the map
//Set the map options object properties
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: {
lat: 37.7884162,
lng: -122.4127457
},
zoom: 14
});
var infowindow = new google.maps.InfoWindow();
var marker;
for(var i = 0; i < locations.length; i++) {
(function() {
// get the position fronm the locations array
var position = locations[i].latlng;
var title = locations[i].name;
//create a marker per location and put into markers array
var marker = new google.maps.Marker({
map: map,
position: position,
title: title,
animation: google.maps.Animation.DROP
//id: i
});
//push the marker to our array of markers
markers.push(marker);
//extend the boundaries of the map for each marker
marker.addListener('click', function() {
populateInfoWindow(this, infowindow);
infowindow.setContent(infoContent);
});
})(i);//end of closure
}//end of for loop
}; //end initMap()
function populateInfoWindow(marker, infowindow) {
//check to make sure the infowindow is not already opened in this marker
if (infowindow.marker != marker) {
infowindow.marker = marker;
infowindow.setContent('<div>' + marker.title + '</div>' + marker.infoContent);
infowindow.open(map, marker);
//Make sure the marker property is cleared if the infowindow is closed
infowindow.addListener('closeclick', function() {
infowindow.setMarker = null;
});
}
}// end of populateInfoWindow
$.ajax({
method: "GET",
crossDomain: true,
url: "https://developers.zomato.com/api/v2.1/search?count=6&lat=37.79161&lon=-122.42143&establishment_type=6",
dataType: "json",
async: true,
headers: {
"user-key": "0a661374a6b58eb2fa84142d27fe81ca"
},
success: function(data) {
var pubs = [];
pubs = data.restaurants;
for(var j = 0; j < pubs.length; j++) {
(function(val) {
infoContent = "<div class='name'>" + "Pub: " + pubs[j].restaurant.name + "</div>" + "\n" + "<div class='cuisines'>" + pubs[j].restaurant.cuisines + "</div>";
})(j);
}
},
error: function() {
infoContent = "<div>Sorry, data is not coming through. Refresh and try again.</div>";
}
});//end of $.ajax call
<!doctype html>
<html class="no-js" lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Map</title>
<link rel="stylesheet" href="css/foundation.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div class="grid-container">
<div class="grid-x grid-padding-x">
<div class="large-12 cell">
</div>
</div>
<div class="grid-x grid-padding-x">
<div class="large-12 cell">
<div class="callout">
<div id="map" class="flex-video">
<iframe width="420" height="315" src="" frameborder="0" allowfullscreen></iframe>
</div>
</div>
</div>
</div>
</div>
<script src="js/vendor/jquery.js"></script>
<script src="js/vendor/what-input.js"></script>
<script src="js/vendor/foundation.js"></script>
<script src="js/map.js"></script>
<script async deter src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBS6v85DRLDI_VKGgNdgQ6EVzDxJfZZOF8&ve&3&libraries=places,drawing&callback=initMap">
</script>
</body>
</html>
The indicated line below is wrong, remove it and your code works:
marker.addListener('click', function() {
populateInfoWindow(this, infowindow);
// infowindow.setContent(infoContent); <<<<<<<<<<<< REMOVE
});
proof of concept fiddle
code snippet:
var map;
var markers = [];
var cuisines, name, establishment, locality, menu, photos, rating, infoContent;
var locations = [
{name: 'The Pub at Ghirardelli Square', latlng: {lat: 37.8063722222, lng: -122.4228888889}},
{name: 'The Irish Bank', latlng: {lat: 37.7902750000, lng: -122.4048472222}},
{name: 'Rogue San Francisco Public House', latlng: {lat: 37.8001440000, lng: -122.4104550000}},
{name: 'Chieftain Irish Restaurant & Pub', latlng: {lat: 37.7814900000, lng: -122.4051510000}},
{name: 'Kennedy\'s Irish Pub and Curry House', latlng: {lat: 37.8042510000, lng: -122.4156040000}},
{name: 'Murphy\'s Pub', latlng: {lat: 37.7901916667, lng: -122.4038472222}}
];
//create instance of a map from the Google Maps API
//Grab the reference to the "map" id to display the map
//Set the map options object properties
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: {
lat: 37.7884162,
lng: -122.4127457
},
zoom: 14
});
var infowindow = new google.maps.InfoWindow();
var marker;
for (var i = 0; i < locations.length; i++) {
(function() {
// get the position fronm the locations array
var position = locations[i].latlng;
var title = locations[i].name;
//create a marker per location and put into markers array
var marker = new google.maps.Marker({
map: map,
position: position,
title: title,
animation: google.maps.Animation.DROP,
infoContent: "there is no infoContent!"
//id: i
});
//push the marker to our array of markers
markers.push(marker);
//extend the boundaries of the map for each marker
marker.addListener('click', function() {
populateInfoWindow(this, infowindow);
});
})(i); //end of closure
} //end of for loop
}; //end initMap()
function populateInfoWindow(marker, infowindow) {
//check to make sure the infowindow is not already opened in this marker
if (infowindow.marker != marker) {
infowindow.marker = marker;
infowindow.setContent('<div>' + marker.title + '</div>' + marker.infoContent);
infowindow.open(map, marker);
//Make sure the marker property is cleared if the infowindow is closed
infowindow.addListener('closeclick', function() {
infowindow.setMarker = null;
});
}
} // end of populateInfoWindow
$.ajax({
method: "GET",
crossDomain: true,
url: "https://developers.zomato.com/api/v2.1/search?count=6&lat=37.79161&lon=-122.42143&establishment_type=6",
dataType: "json",
async: true,
headers: {
"user-key": "0a661374a6b58eb2fa84142d27fe81ca"
},
success: function(data) {
var pubs = [];
pubs = data.restaurants;
for (var j = 0; j < pubs.length; j++) {
(function(val) {
infoContent = "<div class='name'>" + "Pub: " + pubs[j].restaurant.name + "</div>" + "\n" + "<div class='cuisines'>" + pubs[j].restaurant.cuisines + "</div>";
})(j);
}
},
error: function() {
infoContent = "<div>Sorry, data is not coming through. Refresh and try again.</div>";
}
}); //end of $.ajax call
google.maps.event.addDomListener(window, "load", initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map"></div>
The discovery to this answer is a good exercise in appreciating scope. I also discovered that my data object could ride the same iterator from the for loop for the markers.
//create instance of a map from the Google Maps API
//Grab the reference to the "map" id to display the map
//Set the map options object properties
function initMap() {
map = new google.maps.Map(document.getElementById("map"), {
center: {
lat: 37.7884162,
lng: -122.4127457
},
zoom: 14
});
var marker;
//$.ajax call
$.ajax({
method: "GET",
crossDomain: true,
url: "https://developers.zomato.com/api/v2.1/search?count=6&lat=37.79161&lon=-122.42143&establishment_type=6",
dataType: "json",
async: true,
headers: {
"user-key": "0a661374a6b58eb2fa84142d27fe81ca"
},
success: function(data) {
passZomatoData(data);
},
error: function() {
infoContent = "<div>Sorry, data is not coming through. Refresh and try again.</div>";
}
});//end of $.ajax call
//function passZomatoData()
function passZomatoData(data) {
var infowindow = new google.maps.InfoWindow();
pubs = data.restaurants;
console.log(data);
for(var i = 0; i < locations.length; i++) {
(function() {
// get the position fronm the locations array
var position = locations[i].latlng;
var title = locations[i].name;
var cuisine = pubs[i].restaurant.cuisines;
var address = pubs[i].restaurant.location.address;
console.log(address);
//create a marker per location and put into markers array
var marker = new google.maps.Marker({
map: map,
position: position,
title: title,
cuisine: cuisine,
address: address,
animation: google.maps.Animation.DROP
});
//push the marker to our array of markers
markers.push(marker);
//extend the boundaries of the map for each marker
marker.addListener('click', function() {
populateInfoWindow(this, infowindow);
infowindow.setContent('<div><b>Pub name:<b> ' + marker.title + '</div><div><b>Address:<b> ' + marker.address + '</div><div><b>Cuisine:<b> ' + marker.cuisine + '</div>');
});
})(i);//end of closure
}//end of for loop
}
}; //end initMap()
function populateInfoWindow(marker, infowindow) {
//check to make sure the infowindow is not already opened in this marker
if (infowindow.marker != marker) {
infowindow.marker = marker;
//infowindow.setContent('<div>' + marker.title + '</div>' + marker.infoContent);
infowindow.open(map, marker);
//Make sure the marker property is cleared if the infowindow is closed
infowindow.addListener('closeclick', function() {
infowindow.setMarker = null;
});
}
}// end of populateInfoWindow
I am trying to generate Google Map markers with Wikipedia AJAX data in the infowindow using a for loop. I think there is a timing issue occurring, but after several weeks I cannot figure out how to resolve it. When I hardcode an identifier into the for loop to replace i (2 for example), the code works just fine...but when I use i, I get errors saying 'cannot read property [whatever] of undefined. I've played around with setTimeout and callbacks, but I can't seem to figure it out.
Here is my code:
var map;
var marker;
var infowindow;
var wikiURL;
var i;
var text;
var venueInfo;
var markers = [];
var markerNames = [];
var wikiURLs = [];
var venueArray = [];
//The Model - Pro/Collegiate Stadiums in PGH, Pa.
var venues = [
{
name: "PNC Park",
lat: 40.446855,
lng: -80.0056666
},
{
name: "Heinz Field",
lat: 40.4466765,
lng: -80.01576
},
{
name: "PPG Paints Arena",
lat: 40.439593,
lng: -79.989338
},
{
name: "Highmark Stadium",
lat: 40.4362358,
lng: -80.00959209999999
},
{
name: "Peterson Events Center",
lat: 40.443828,
lng: -79.962283
}
];
//marker creator
function createMarker(){
for (i=0; i <= venues.length; i++){
wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' +venues[i].name+ '&format=json&callback=wikiCallback';
wikiURLs.push(wikiURL);
$.ajax ({
url: wikiURL,
dataType: "jsonp",
success: function(data){
text = data[2];
venueInfo = text[0];
console.log(venueInfo);
marker = new google.maps.Marker({
position: {lat: venues[i].lat, lng: venues[i].lng},
map: map,
draggable: false,
content: '<h2>'+venues[i].name+'</h2><p>'+venueInfo+'</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function(){
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
});
}
}
//Map Initializer
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 40.446855, lng: -80.0056666},
zoom: 14,
mapTypeId: 'satellite'
});
//viewmodel();
createMarker();
}
<!DOCTYPE html>
<html>
<head>
<link rel='stylesheet' href='css/bootstrap-theme.min.css'>
<link rel='stylesheet' href='css/main.css'>
</head>
<body>
<nav>
</nav>
<container>
<div id='map'>
</div>
</container>
<script type='text/javascript' src='js/jquery-3.2.1.min.js'></script>
<script type='text/javascript' src='js/knockout-3.4.2.js'></script>
<script type='text/javascript' async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA_WObUiYD7YpoYufR84re1LZHAJeAGXkY&v=3&callback=initMap">
</script>
<script type='text/javascript' src='js/app.js'></script>
</body>
As #jeff carey said, fix your loop and move your ajax code to separate function
function doAjax(i){
wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&search=' +venues[i].name+ '&format=json&callback=wikiCallback';
wikiURLs.push(wikiURL);
$.ajax ({
url: wikiURL,
dataType: "jsonp",
success: function(data){
text = data[2];
venueInfo = text[0];
marker = new google.maps.Marker({
position: {lat: venues[i].lat, lng: venues[i].lng},
map: map,
draggable: false,
content: '<h2>'+venues[i].name+'</h2><p>'+venueInfo+'</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function(){
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
});
}
function createMarker(){
for (i=0; i < venues.length; i++){
doAjax(i);
}
}
You have a common problem caused by calling an asynchronous function inside a loop. One way to fix the issue (i is past the end of the input array when the callback functions run) is with a Immediately-Invoked Function Expression (IIFE) which holds closure on the i variable, so when the callback function is executed, it has the "correct" value:
success: (function(i) {
return function(data) {
text = data[2];
venueInfo = text[0];
console.log(venueInfo);
marker = new google.maps.Marker({
position: {
lat: venues[i].lat,
lng: venues[i].lng
},
map: map,
draggable: false,
content: '<h2>' + venues[i].name + '</h2><p>' + venueInfo + '</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function() {
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
}(i))
proof of concept fiddle
(working) code snippet:
var map;
var marker;
var infowindow;
var wikiURL;
var i;
var text;
var venueInfo;
var markers = [];
var markerNames = [];
var wikiURLs = [];
var venueArray = [];
//The Model - Pro/Collegiate Stadiums in PGH, Pa.
var venues = [{
name: "PNC Park",
lat: 40.446855,
lng: -80.0056666
},
{
name: "Heinz Field",
lat: 40.4466765,
lng: -80.01576
},
{
name: "PPG Paints Arena",
lat: 40.439593,
lng: -79.989338
},
{
name: "Highmark Stadium",
lat: 40.4362358,
lng: -80.00959209999999
},
{
name: "Peterson Events Center",
lat: 40.443828,
lng: -79.962283
}
];
//marker creator
function createMarker() {
for (i = 0; i < venues.length; i++) {
wikiURL = 'https://en.wikipedia.org/w/api.php?action=opensearch&search=' + venues[i].name + '&format=json&callback=wikiCallback';
wikiURLs.push(wikiURL);
$.ajax({
url: wikiURL,
dataType: "jsonp",
success: (function(i) {
return function(data) {
text = data[2];
venueInfo = text[0];
console.log(venueInfo);
marker = new google.maps.Marker({
position: {
lat: venues[i].lat,
lng: venues[i].lng
},
map: map,
draggable: false,
content: '<h2>' + venues[i].name + '</h2><p>' + venueInfo + '</p>'
});
markerNames.push(venues[i].name);
markers.push(marker);
infowindow = new google.maps.InfoWindow({
content: this.content
});
marker.addListener('click', function() {
infowindow.setContent(this.content);
infowindow.open(map, this);
});
}
}(i))
});
}
}
//Map Initializer
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 40.446855,
lng: -80.0056666
},
zoom: 14,
mapTypeId: 'satellite'
});
//viewmodel();
createMarker();
}
html,
body,
#map {
height: 100%;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<container>
<div id='map'>
</div>
</container>
<script type='text/javascript' async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap">
</script>
I have the following Ajax request on a select drop down change which simply gets the records from the controller, Loop through each one and get the latitude | longitude and pushes it to an array.
Then in the same ajax success i pass that lat and lng array to google map.
But the map doesn't shows up..
$(document).ready(function() {
$('.selectCity').change(function() {
var city = $(this).val();
$.ajax({
type: 'GET',
url: '/riders/location/track',
data: {
'city': city
},
success: function(data) {
var lat = [];
var lng = [];
//Get Locations and push it to lat and lng
$.each(data, function(index, value) {
$.each(value, function(index1, value1) {
console.log(value1.rider_location.lat);
lat.push(value1.rider_location.lat);
lng.push(value1.rider_location.lng);
});
});
//Google Map
google.maps.event.addDomListener(window, 'load', init);
function init() {
var locations = [
['Rider', lat, lng]
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
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]),
map: map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
}
});
});
});
Plus please suggest best practice also.
Of course I can make my comment above as an answer.
You can also listen to the "google-maps-ready"-event in the script-url by using the callback-parameter (HTML):
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?libraries=geometry,places&callback=initialize">
</script>
JS:
// In this way you have to define a function called initialize which should be defined globally otherwise it can not be found by the google-library.
// unfortunately this map-variable is defined globally here but you can also wrap the whole code below by using an IIFE.
var map;
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
// you might set a center here or wait untill you have got some markers fetched via ajax, you can then use the first/last or some other marker respecetive it's position(lat,long) to set as "starting point"
//center: {lat: LAT, lng: LONG }
mapTypeId: google.maps.MapTypeId.ROADMAP
});
}
// Although I have no access to your website to test this code below, it might be done in this way:
$(document).ready(function () {
$('.selectCity').change(function () {
var city = $(this).val();
$.ajax({
type: 'GET',
url: '/riders/location/track',
data: {
'city': city
},
success: function (data) {
var positions = [];
//Get Locations and push it to lat and lng
// you can also use just one array to insert all locations and "labels" into
$.each(data, function (index, value) {
$.each(value, function (index1, value1) {
console.log(value1.rider_location.lat);
positions.push({
lat: value1.rider_location.lat,
lng: value1.rider_location.lng,
content: 'Rider' // do you get some text with each location?
});
});
});
// set "starting point" afterwards
map.setCenter({
lat: positions[0].lat,
lng: positions[0].lng
});
var infowindow = new google.maps.InfoWindow();
var marker,
i;
for (i = 0; i < positions.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(positions[i].lat, positions[i].lng),
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(positions[i].content);
infowindow.open(map, marker);
}
}) (marker, i));
}
}
});
});
});
Hope it helps!
I am trying to update the location of a marker with out refreshing the whole page. I have tried to use setTimeout(function() however I am having no luck..
here is my code I have so far..
thanks in advance
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(35.66, -80.50),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var json = (function () {
var json = null;
$.ajax({
'async': false,
'global': false,
'url': "getjson.php",
'dataType': "json",
'success': function (data) {
json = data; } });
return json;})();
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data.title
});
}
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
(function(marker, data) {
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
google.maps.event.addDomListener(window, 'load', initialize);
here is my JSON output.
[{"lat":35.6606376,"lng":-80.5048653,"content":"bca"}, {"lat":42.6799504,"lng":-36.4949205,"content":"abc"}]
I would suggest using setInterval rather than setTimeout.
Here is some code that simulates an update via JSON in a fiddle, using your provided JSON with the required "description" member added for each marker:
var map = null;
var gmarkers = [];
var intervalNumber = 0;
setInterval(function () {
new Request.JSON({
url: '/echo/json/',
data: {
json: JSON.encode([{
"lat": 35.6606376 + (0.01 * intervalNumber),
"lng": -80.5048653 + (0.1 * intervalNumber),
"content": "bca",
"description":"first marker"
}, {
"lat": 42.6799504 + (0.01 * intervalNumber),
"lng": -36.4949205 - (0.1 * intervalNumber),
"content": "abc",
"description": "second marker"
}]),
delay: 3
},
onSuccess: function (response) {
update_map(response);
intervalNumber++;
}
}).send();
}, 5000);
update_map = function (data) {
var bounds = new google.maps.LatLngBounds();
// delete all existing markers first
for (var i = 0; i < gmarkers.length; i++) {
gmarkers[i].setMap(null);
}
gmarkers = [];
// add new markers from the JSON data
for (var i = 0, length = data.length; i < length; i++) {
latLng = new google.maps.LatLng(data[i].lat, data[i].lng);
bounds.extend(latLng);
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data[i].title
});
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.description+"<br>"+marker.getPosition().toUrlValue(6));
infoWindow.open(map, marker);
});
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.description+"<br>"+marker.getPosition().toUrlValue(6));
infoWindow.open(map, marker);
});
})(marker, data[i]);
gmarkers.push(marker);
}
// zoom the map to show all the markers, may not be desirable.
map.fitBounds(bounds);
};
function initialize() {
// initialize the map on page load.
var mapOptions = {
center: new google.maps.LatLng(35.66, -80.50),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
// add the markers to the map if they have been loaded already.
if (gmarkers.length > 0) {
for (var i = 0; i < gmarkers.length; i++) {
gmarkers[i].setMap(map);
}
}
}
google.maps.event.addDomListener(window, 'load', initialize);
https://developers.google.com/maps/documentation/javascript/reference
markerObject.setPosition(latlng:LatLng|LatLngLiteral)
I don't think you need to redraw the map, but in case you do:
google.maps.event.trigger(mapObject, 'resize');