I have set an onclick with a variable on a link that calls the calcRoute function for Google maps, and everytime I click the link it says the following Uncaught ReferenceError: NE461UL is not defined The parameter is a postcode by the way.
I have been trying for a while and I can't figure out why it is showing an error.
I have a jquery file with the following line
var distLink = "<a onclick=\"calcRoute(" + postcode + "); return false;\" datalat=" + lat + " datalng=" + lng + " id=\"get-directions\" class=\"directions" + letter +"\">Directions<\/a>";
The calcRoute is in my header
function calcRoute(postcode) {
console.log(marker);
var start = document.getElementById("address").value;
var end = document.getElementById("get-directions").name;
$('get-directions').click(function(){
console.log('click!');
});
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.DRIVING
};
console.log(JSON.stringify(request));
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
}
postcode must be passed as a string (extra pair of quotation marks around it):
distLink = "<a onclick=\"calcRoute('" + postcode + "'); return false;\" datalat=" + lat + " datalng=" + lng + " id=\"get-directions\" class=\"directions" + letter +"\">Directions<\/a>";
Related
My goal is to automate process of route calculation from A to B in Google Maps by using JavaScript + Google Distance Matrix Service. I would like to find route which is the fastest (based on current traffic). Script should calculate route by using current date and time.
<script src="https://maps.google.com/maps/api/js?sensor=false"></script>
<script>
function init() {
var service = new google.maps.DistanceMatrixService;
var origin = 'Great,Lake,8';
var destination = 'Lake,Great,21';
service.getDistanceMatrix({
origins: [origin],
destinations: [destination],
travelMode: google.maps.TravelMode.DRIVING,
unitSystem: google.maps.UnitSystem.METRIC,
drivingOptions: {
departureTime: new Date(Date.now()), // for the time N milliseconds from now.
trafficModel: "best_guess"
}
}, function(response, status) {
if (status !== google.maps.DistanceMatrixStatus.OK) {
alert('Error was: ' + status);
} else {
<!-- The same accessing of elements in object
-->
<!-- document.getElementById("result").innerHTML += '1)' + JSON.stringify(response.rows[0].elements[0].distance.text) + '<br>';
document.getElementById("result").innerHTML += '2)' + JSON.stringify(response.rows[0].elements[0]['distance']['text']) + '<br>';;
document.getElementById("result").innerHTML += '3) RESPONSE: ' + JSON.stringify(response) +'<br><br>'; -->
document.getElementById("result").innerHTML += 'RESULT: ' + JSON.stringify(response);
alert(response.originAddresses[0] + ' ' + response.destinationAddresses[0] + ' ==> ' + response.rows[0].elements[0].duration.text + ' ' + response.rows[0].elements[0].distance.text);
}
});
}
</script>
<body onload="init()">
<div id="result">
</div>
</body>
Code works only if drivingOptions is removed. But I need this object - because I would like to calculate route based on traffic situation. I am executing script in https://jsfiddle.net/ - so I don't see any errors - except that when I removed drivingOptions object I saw that pop up with time and distance shown in pop up.
I am making a basic web-based weather app, which detects the current weather conditions in the user's location. My current code so far does work, but is missing an important feature - I want the background of the web page to change according to the user's location and weather conditions. For instance - if a user is in New York and the weather is sunny, I would like to display any New York based popular image(ex: Times Square) along with sunny skies as the body background. I've searched several APIs but haven't found any that meets my needs.
In my current code, I'm using IPInfo.io to get the user's location and OpenWeatherMap to get the weather conditions.
This pen has my code (NOTE - code for units hasn't been added yet), and here's the JS bit -
var lat = 0.0,
lon = 0.0;
var testURL = 'http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=2de143494c0b295cca9337e1e96b00e0';
var myURL = 'http://api.openweathermap.org/data/2.5/weather?lat=' + lat + '&lon=' + lon + '&appid="ae0acb60e8db4952e081c2fb470a1b23"';
var city = '',
state = '',
country = '',
postal = 0;
//if (navigator.geolocation) {
// /* geolocation is available */
// navigator.geolocation.getCurrentPosition(function (position) {
// lat = position.coords.latitude;
// lon = position.coords.longitude;
// console.log("Latitude = " + lat);
// console.log("Longitude = " + lon);
//
// display(position.coords.latitude, position.coords.longitude);
// });
//
//} else {
// /* geolocation IS NOT available */
// $("#jumbotron").html("geolocation not available");
//
//}
//get co-ordinates using ipinfo.io
$.getJSON('http://ipinfo.io', function (data) {
console.log(data);
var loc = data.loc;
lat = loc.split(",")[0];
lon = loc.split(",")[1];
display(lat, lon);
city = data.city;
state = data.region;
country = data.country;
postal = parseInt(data.postal, 10);
})
function display(x, y) {
$("#pos1").html("<b>" + x + "</b>");
$("#pos2").html("<b>" + y + "</b>");
}
//function to calculate wind direction from degrees
function degToCompass(num) {
//num = parseInt(num, 10);
console.log("Inside degtocompass = " + num);
var val = Math.floor((num / 22.5) + 0.5);
var arr = ["N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"];
return arr[(val % 16)];
}
//function to return current temperature
function convertTemp(currTemp) {
//get celsius from kelvin
return Math.round(currTemp - 273.15);
}
$("button").click(function () {
console.log("In Latitude = " + lat);
console.log("In Longitude = " + lon);
//prepare api call
$.ajax({
url: 'http://api.openweathermap.org/data/2.5/weather?lat=' + lat + '&lon=' + lon + '&appid=ae0acb60e8db4952e081c2fb470a1b23',
//url: testURL,
type: 'GET', // The HTTP Method, can be GET POST PUT DELETE etc
data: {}, // Additional parameters here
dataType: 'json',
success: function (data) {
console.log(data);
//---------get the clipart---------------
var picLink = 'http://openweathermap.org/img/w/';
var picName = data.weather[0].icon;
picLink += picName + ".png";
$("#picture").empty().append('<img src="' + picLink + '">');
//----------get the temperature-----------
var curTemp = convertTemp(data.main.temp);
console.log("Current temp = " + curTemp);
//$("#temp").empty().append("<b>" + curTemp + "</b>");
$("#picture").append("<b>" + curTemp + "</b>");
//----------get the place----------------------
var area = city + ", " + state + ", " + country;
$("#area").empty().append("<b>" + area + "</b>");
//----------get weather conditions------------
$("#conditions").empty().append("<b>" + data.weather[0].description + "</b>");
//----------get wind speed------------
//get wind direction
var windSpeed = degToCompass(data.wind.deg);
//add wind speed
windSpeed += ' ' + data.wind.speed;
//display wind speed
$("#wind-speed").empty().append("<b>" + windSpeed + "</b>");
},
error: function (err) {
alert(err);
},
beforeSend: function (xhr) {
//xhr.setRequestHeader("X-Mashape-Authorization", "32ROUuaq9wmshfk8uIxfd5dMc6H7p1lqdZSjsnXkB5bQtBteLK"); // Enter here your Mashape key
}
});
});
Well... First of all there is no need to use WebServices, but you can't do it without any API. As I can see you use openweathermap API . As far as I know this API returns both longitude and latitude, so you can use these values as input to another request to a photo API (like flickr) to get the image you want. Moreover openweathermap API returns city name which can make your photo request even more accurate.
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 8 years ago.
im trying to assign the value of my address to another variable but all i get is undefined or something like my url in the variable
here is my coding. i almost crack my head because of this.
function geoCoding(displayname, trackerModel, setupType, marker, index){
var setupMessageInfoWindow;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': marker.getPosition()}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
var location = results[1].formatted_address;
} else {
alert('No results found at marker ' + marker.position);
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
setupMessageInfoWindow = "<div height=\"300\" width=\"300\"><b>" + displayname + "</b>"
+ " <br> Location : " + location
//+ " <br> Tracker id : " + userid
//+ " <br> imei : " + imei
+ " <br> Tracker Type : " + trackerModel
//+ " <br> Mobile Number : " +
//+ " <br> Location : " + location;
+ " <br> " + setupType
+ "</div>" ;
return setupMessageInfoWindow;
}
geocode is asynchronous so setupMessageInfoWindow variable is created before variable location is properly set. If you want to set some info window you can call a function from geocode() when location is successfully retrieved. For example:
function setContent(marker, content) {
infoWin.setContent(content);
google.maps.event.addListener(marker, 'click', function() {
infoWin.open(map, marker);
});
}
function geoCoding(displayname, trackerModel, setupType, marker, index){
var setupMessageInfoWindow;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': marker.getPosition()}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log('status ok');
console.log(results);
if (results[1]) {
var location = results[1].formatted_address;
setupMessageInfoWindow = "<div height=\"300\" width=\"300\"><b>" + displayname + "</b>"
+ " <br> Location : " + location
//+ " <br> Tracker id : " + userid
//+ " <br> imei : " + imei
+ " <br> Tracker Type : " + trackerModel
//+ " <br> Mobile Number : " +
//+ " <br> Location : " + location;
+ " <br> " + setupType
+ "</div>" ;
setContent(marker, setupMessageInfoWindow);
} else {
console.log('No results found at marker ' + marker.position);
}
} else {
console.log('Geocoder failed due to: ' + status);
}
});
}
See example at jsbin. There is click event handler set for marker which shows location found.
So you have probably seen something similar alot, where someone has a problem with using the "i" variable in a functions inside a for loop. Now that can easily be fixed with:
(function(){
return function() {
//something
}
})(i);
But, how do I do this in my scenario?
GMap.prototype.drawDirection = function (directionsRenderer, directionsService, headMarker, tailMarkers, callback) {
var request;
var array = [];
var count = 0;
for (var i = 0; i < tailMarkers.length; i++) {
count = i;
request = {
origin: headMarker.getPosition(),
destination: tailMarkers[i].getPosition(),
travelMode: google.maps.DirectionsTravelMode.DRIVING,
unitSystem: google.maps.DirectionsUnitSystem.METRIC
};
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(response);
console.log(i + " " + count);
callback(response.routes[0].legs[0].distance.value, i, tailMarkers.length - 1);
} else {
alert('Error: ' + status);
}
});
}
};
To be more accurate, it's about the directionsService object:
directionsService.route(request, function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(response);
console.log(i + " " + count);
callback(response.routes[0].legs[0].distance.value, i, tailMarkers.length - 1);
} else {
alert('Error: ' + status);
}
});
Now, I don't want to use JFiddle since it would be alot to write, so I'm just going to link to my site where I'm trying this.
http://stud.aitel.hist.no/~andersfy/html5.proj/
If you look at the checkbox in the bottom right corner, where it says "vis min posisjon" you just need to click on that, and you'll see the problem.
The code is in the file galled GMap.js at line 134 to 142.
I hope I'm giving you enough information!
You should not create functions inside of for loops for this very reason.
Your problem is in this closure, that shares the variable i:
function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(response);
console.log(i + " " + count);
callback(response.routes[0].legs[0].distance.value, i, tailMarkers.length - 1);
} else {
alert('Error: ' + status);
}
}
I would rewrite that function to not depend on i, but if you need i then
/*before your for loop */
function createRouter(i){
return function (response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsRenderer.setDirections(response);
console.log(i + " " + count);
callback(response.routes[0].legs[0].distance.value, i, tailMarkers.length - 1);
} else {
alert('Error: ' + status);
}
}
};
/* in your for loop */
directionsService.route(request, createRouter(i));
I am trying to have a function for calculating routes for google maps be dynamically changed based on data retrieved from a .getJSON. I have tried including the bulk of the function calcRoute() under a .done function, but I am receiving an error in property waypoints in the javascript console. I am at a loss as what to do, because when I don't include the bulk of the function under the .done, the array remains blank (asynchronous call with the .getJSON. Here is the code to give you a better idea:
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var waypts = [];
var data = $.getJSON("/westcoast_map.php", {
westcoast_id: $('.opener').data('westcoast_id')
}, function(json) {
return json[1];
});
data.done(function(theData) {
waypts = theData[1];
console.log(waypts); //this spits out the array in the proper format, i.e. {location:city, state, stopover:true},...etc...
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById('directions_panel');
summaryPanel.innerHTML = '';
// For each route, display summary information.
for (var i = 0; i < route.legs.length; i++) {
var routeSegment = i + 1;
summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + '</b><br>';
summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
summaryPanel.innerHTML += route.legs[i].end_address + '<br>';
summaryPanel.innerHTML += route.legs[i].distance.text + '<br><br>';
}
}
});
});
}
i'm still not sure what you problem is, because the code pared you show, should at least work from the logical part. but there are parts where it is not clear what you try to achive:
var data = $.getJSON("/westcoast_map.php", {
westcoast_id: $('.opener').data('westcoast_id')
}, function(json) {
return json[1];
});
if you expect here that data will become json[1], then your assumption is wrong.
$.getJSON returns always jQuery XHR. the callback function will be called later when the browser received the data.
Here a little example to understand how async works:
the callback functions 1 and 2 are called when the client gets the response for the request, but not before the original script was completely executed, so doSomethingElse() will be always called before the callback function 1 and 2 are executed.
the order in which callback function 1 and 2 are executed depends on which response arrives first.
var test = [];
preparesSomeStuff();
$.getJSON("someurl1",{},function() {
//Callback Function 1
});
doSomething();
$.getJSON("someurl2",{},function() {
//Callback Function 2
});
doSomethingElse();
//<<END OF SCRIPT>>
if you don't want to have your whole code inside of the callback function (e.g. because of readability) you could do it the following way:
function calcRoute() {
var start = document.getElementById('start').value;
var end = document.getElementById('end').value;
var waypts = [];
$.getJSON("/westcoast_map.php", {
westcoast_id: $('.opener').data('westcoast_id')
}, function(theData) {
calcualteRoute(theData[1], start, end);
});
//if you place code here it will be executed before displayResult will be called because getJSON is async
}
function calcualteRoute(waypts, start, end) {
console.log(waypts); //this spits out the array in the proper format, i.e. {location:city, state, stopover:true},...etc...
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
displayResult(response,status);
}
});
//if you place some code here it will be executed BEFORE displayResult will be called, because
//directionsService.route is async
}
function displayResult(response, status) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
var summaryPanel = document.getElementById('directions_panel');
summaryPanel.innerHTML = '';
// For each route, display summary information.
for (var i = 0; i < route.legs.length; i++) {
var routeSegment = i + 1;
summaryPanel.innerHTML += '<b>Route Segment: ' + routeSegment + '</b><br>';
summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
summaryPanel.innerHTML += route.legs[i].end_address + '<br>';
summaryPanel.innerHTML += route.legs[i].distance.text + '<br><br>';
}
}