I'm Stucked in a situation where i need to fix my codes when getting Jsonresult for my Google Maps v3 but when i am in the loop to load my map with worker from jquery, this error shows Uncaught TypeError: Cannot call method 'toLowerCase' of undefined i don't know how to fix this and i dont see some fixtures with this problem . I hope Someone can help me with this
This is my Codes for my Javascript:
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
var minZoomLevel = 4;
var zooms = 7;
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById('map'), {
zoom: minZoomLevel,
center: new google.maps.LatLng(38.50, -90.50),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Bounds for North America
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(15.70, -160.50),
new google.maps.LatLng(68.85, -55.90)
);
// Listen for the dragend event
google.maps.event.addListener(map, 'dragend', function () {
if (strictBounds.contains(map.getCenter())) return;
// We're out of bounds - Move the map back within the bounds
var c = map.getCenter(),
x = c.lng(),
y = c.lat(),
maxX = strictBounds.getNorthEast().lng(),
maxY = strictBounds.getNorthEast().lat(),
minX = strictBounds.getSouthWest().lng(),
minY = strictBounds.getSouthWest().lat();
if (x < minX) x = minX;
if (x > maxX) x = maxX;
if (y < minY) y = minY;
if (y > maxY) y = maxY;
map.setCenter(new google.maps.LatLng(y, x));
});
// Limit the zoom level
google.maps.event.addListener(map, 'zoom_changed', function () {
if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
});
}
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
function codeAddress() {
$.getJSON("/Dashboard/LoadWorkerList", function (address) {
var infowindow = new google.maps.InfoWindow();
$.each(address,function (index,currVal) {
currVal = $(this).val();
geocoder.geocode({ 'address': currVal }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
icon: iconBase + 'man.png',
position: results[0].geometry.location,
title: currVal
})
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(currVal);
infowindow.open(map, marker);
}
})(marker, currVal));
address.push(marker);
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
});
});
return true;
}
window.onload = function () {
initialize();
codeAddress();
}
</script>
This is the code for LoadWorkerList
public JsonResult LoadWorkerList()
{
var workerList = new List<Worker_Address>();
// check if search string has value
// retrieve list of workers filtered by search criteria
var list = (from a in db.Worker_Address
where a.LogicalDelete == false
select a).ToList();
List<WorkerAddressInfo> wlist = new List<WorkerAddressInfo>();
foreach (var row in list)
{
WorkerAddressInfo ci = new WorkerAddressInfo
{
ID = row.ID,
Worker_ID = row.WorkerID,
AddressLine1 = row.Address_Line1 + " " + row.Address_Line2+ " " +row.City + " "+ GetLookupDisplayValById(row.State_LookID),
LogicalDelete = row.LogicalDelete
};
wlist.Add(ci);
}
return Json(wlist.ToList().OrderBy(p => p.AddressLine1), JsonRequestBehavior.AllowGet);
}
The Error is in this ff: codes
Uncaught TypeError: Cannot call method 'toLowerCase' of undefined
v.fn.extend.val jquery-1.8.3.min.js:2
(anonymous function) $.each(address,function (index,currVal) {
v.extend.each jquery-1.8.3.min.js:2
(anonymous function) currVal = $(this).val();
l jquery-1.8.3.min.js:2
c.fireWith jquery-1.8.3.min.js:2
T jquery-1.8.3.min.js:2
r
ok, judging by the stacktrace, it's saying that;
- either the value being returned by $(this).val() in currVal = $(this).val(); is undefined at a certain index, or
- the value of one of the indexes in address at $.each(address,function (index,currVal) is undefined.
make sure that the index value in $.each(address,function (index,currVal) { is not going beyond the length of address and that ALL the elements in address is assigned a value
I'm guessing you're trying to do geocoding on an address in the array address, and it's trying to make the address a lowerCase string, but there's no string being found.
if address is not an array, make it an array, it shouldn't be a string
Related
I have a problem because i want to use this Json Result that returns Json List but my problem is how should i call the json result that i will be using to geocode and add marker to my Google Maps ? I used getJson and its not functioning but i dont tried yet the .ajax function
Here is my sets of codes:
<script type="text/javascript">
var geocoder;
var map;
function initialize() {
var minZoomLevel = 4;
var zooms = 7;
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById('map'), {
zoom: minZoomLevel,
center: new google.maps.LatLng(38.50, -90.50),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Bounds for North America
var strictBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(15.70, -160.50),
new google.maps.LatLng(68.85, -55.90)
);
// Listen for the dragend event
google.maps.event.addListener(map, 'dragend', function () {
if (strictBounds.contains(map.getCenter())) return;
// We're out of bounds - Move the map back within the bounds
var c = map.getCenter(),
x = c.lng(),
y = c.lat(),
maxX = strictBounds.getNorthEast().lng(),
maxY = strictBounds.getNorthEast().lat(),
minX = strictBounds.getSouthWest().lng(),
minY = strictBounds.getSouthWest().lat();
if (x < minX) x = minX;
if (x > maxX) x = maxX;
if (y < minY) y = minY;
if (y > maxY) y = maxY;
map.setCenter(new google.maps.LatLng(y, x));
});
// Limit the zoom level
google.maps.event.addListener(map, 'zoom_changed', function () {
if (map.getZoom() < minZoomLevel) map.setZoom(minZoomLevel);
});
}
var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/';
function codeAddress() {
var infowindow = new google.maps.InfoWindow();
$.getJson("Dashboard/DashboardIndex",null , function(address) {
$.each(address, function () {
var currVal = $(this).val();
address.each(function () {
geocoder.geocode({ 'address': currVal }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
icon: iconBase + 'man.png',
position: results[0].geometry.location,
title: currVal
})
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(currVal);
infowindow.open(map, marker);
}
})(marker, currVal));
address.push(marker);
}
else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
setTimeout(codeAddress, 2000);
}
else {
alert("Geocode was not successful for the following reason: " + status);
}
});
});
});
});
return false;
}
window.onload = function () {
initialize();
codeAddress();
}
</script>
And my JsonResult at my Controller
public JsonResult LoadWorkerList()
{
var workerList = new List<Worker_Address>();
// check if search string has value
// retrieve list of workers filtered by search criteria
var list = (from a in db.Worker_Address
where a.LogicalDelete == false
select a).ToList();
List<WorkerAddressInfo> wlist = new List<WorkerAddressInfo>();
foreach (var row in list)
{
WorkerAddressInfo ci = new WorkerAddressInfo
{
ID = row.ID,
Worker_ID = row.WorkerID,
AddressLine1 = row.Address_Line1 + " " + row.Address_Line2+ " " +row.City + " "+ GetLookupDisplayValById(row.State_LookID),
LogicalDelete = row.LogicalDelete
};
wlist.Add(ci);
}
return Json(wlist.ToList().OrderBy(p => p.AddressLine1), JsonRequestBehavior.AllowGet);
}
Im thanking some who could help me in Advance :)
It's hard to guess where it goes wrong since you didn't post the JSON format and are getting errors (toLowerCase) of code you haven't posted. I think it's in the following area:
function codeAddress() {
var infowindow = new google.maps.InfoWindow();
$.getJson("Dashboard/DashboardIndex",null , function(address) {
console.log("full json object",address);//<--should show an array of objects
$.each(address, function () {
console.log(this);//<--here you can see what the JSON object is
var currVal = this["AddressLine1"];//<--guess from what your C# code looks like
//next each doesn't make much sense unless you have an array of arrays
// but the C# code makes json for a list (not a list of lists)
You can use IE for your console output but don't bother posting the output here because I can already tell you it's going to be [Object, object]. To get useful info you're going to have to use firefox with firebug or Chrome. To see the console you can press F12
The line:
setTimeout(codeAddress, 2000);
Could be optimized since now when you are making too many requests you'll fetch the entire address list again and start from the beginning instead of "waiting" for 2 seconds and continue where you were.
The following code:
map.setCenter(results[0].geometry.location);
Why set the center of the map within the loop? It'll just end up having the center of the last found address so you may as well do it outside the loop to set the center to last found address.
I have a FF error about the info window in GM. Here is the source code:
var lats;
var longs;
var k;
function initialize() {
//parentArray is an object where the elements of the parent page are stored
var parentArray = window.parent.params;
lats = parentArray["lat"].replace(/^\|+|\|+$/g, '').split("|");
longs = parentArray["long"].replace(/^\|+|\|+$/g, '').split("|");
k = parentArray["keys"].replace(/^\|+|\|+$/g, '').split("|");
var myLatlng = new google.maps.LatLng(parseFloat(lats[0]), parseFloat(longs[0]));
var myOptions = {
zoom: 20,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
//contentString is built based on the array passed by the parent page
for (var i = 0; i < lats.length; i++) {
var contentString = '<div id="content"' + i + '><b>' + k[i] + '</b>';
for (var f in parentArray)
if ((f !== "long") && (f !== "lat") && (f !== "keys") && (parentArray[f].substring(0, 1) !== "<")) {
contentString += '<br />' + f + ': ' + parentArray[f];
}
contentString += '<br /></div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(lats[i]), parseFloat(longs[i])),
map: map,
title: 'Position'
});
createInfoWindow(marker, contentString);
function createInfoWindow(m, content) {
google.maps.event.addListener(m, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, m);
});
}
}
}
params is an array with information and k is an array of keys for the markers on the google map. Does anybody know why do I have a FF error for this code?
Sample Data For params:
params['foo']: bar
params['keys']: "Start Position|End Position"
params['lat']: "12.5323703|13.5323703"
params['long']: "14.5786987|15.5786987"
EDIT:
The Error is: createInfoWindow is not defined
Thanks in advance,
Lajos Arpad.
You are defining your method inside a loop (this is bad on its own..) and you call the method before you define it ..
just moving the call below the definition fixes the issue..
function createInfoWindow(m, content) {
google.maps.event.addListener(m, 'click', function () {
infowindow.setContent(content);
infowindow.open(map, m);
});
}
createInfoWindow(marker, contentString);
Demo at http://jsfiddle.net/gaby/gdLVd/
But you should really move the definition of the createInfoWindow method somewhere else..
Better demo at http://jsfiddle.net/gaby/gdLVd/1/
Here is the code:
<script type="text/javascript">
var offender_locations = [
["10010", "xxxxx", 3],
["10001", "xxxxx", 2],
["10002", "zzzzz", 1]
];
for (i = 0; i < offender_locations.length; i++) {
var address = offender_locations[i][0];
var icon_img = offender_locations[i][1];
}
</script>
This is the output:
1) 10010 - zzzzz
2) 10001 - zzzzz
3) 10002 - zzzzz
AS you can see var address outputs the correct value, but *var icon_img* does always repeat the same value.
I am a Javascript beginner and I have tried all ways I can think of but I still get the same results.
P.S. I have pasted the full script here :
<script type="text/javascript">
var offender_locations = [
["10010", "offender_icon.png", 3],
["10001", "offender_icon.png", 2],
["10002", "visitor_icon.png", 1]
];
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var latlng = new google.maps.LatLng(0, 0);
for (i = 0; i < offender_locations.length; i++) {
var infowindow = new google.maps.InfoWindow();
var geocoder_map = new google.maps.Geocoder();
var address = offender_locations[i][0];
var icon_img = offender_locations[i][1];
geocoder_map.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: map.getCenter(),
icon: icon_img
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(offender_locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
} else {
alert("The requested offender is not mappable !")
};
});
}
</script>
The markers in this script are all # the correct postal code, but they all show the same icon (visitor_icon.png) !
The problem is that you are creating a function in a loop. JavaScript has only function scope, not block scope. I.e. variables you create in a loop exist only once in the whole function, just the values changes per iteration.
At the time icon_img is evaluated (in the callback passed to geocode), the outer for loop already finished and icon_img has the value of the last iteration. It works for address because it is evaluated inside the loop, not later.
You have to 'capture' the current value of icon_img and you can do so by using an immediate function:
for (i = 0; i < offender_locations.length; i++) {
var infowindow = new google.maps.InfoWindow(),
geocoder_map = new google.maps.Geocoder(),
address = offender_locations[i][0],
icon_img = offender_locations[i][1];
(function(addr, img) { // <-- immediate function call
geocoder_map.geocode({'address': addr}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: map,
position: map.getCenter(),
icon: img
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(addr);
infowindow.open(map, marker);
});
} else {
alert("The requested offender is not mappable !");
}
});
}(address, icon_img)); // <-- immediate function call
}
Maybe you hav to do this for even more variables... not sure.
I'm sure this is really simple but I haven't had much luck figuring out what's wrong. I'm creating an empty array (locations), filling it with location objects in the getPartnerLocations function and then trying to plot the locations on the map with the drop function. The problem I'm having is that inside the drop function the locations array which has stuff in it is returning a length of zero so the loop in the isn't working. Any tips or ideas about what's going on here would be greatly appreciated.
var markers = [];
var locations = [];
var iterator = 0;
var map;
var geocoder;
var newYork = new google.maps.LatLng(40.7143528, -74.0059731);
function initialize() {
var mapOptions = {
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: newYork
};
map = new google.maps.Map(document.getElementById("map_canvas"),mapOptions);
}
function getPartnerLocations() {
geocoder = new google.maps.Geocoder();
$('.partner').each(function(index){
var street = $('.partner-streetaddress',this).text();
var city = $('.partner-city',this).text();
var state = $('.partner-state',this).text();
var country = $('.partner-country',this).text();
var address = street + ', ' + city + ', ' + state + ', ' + country;
geocoder.geocode( { 'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
locations.push( results[0].geometry.location );
console.log(locations[index]);
}
else
{
console.log('failed to geocode address: ' + address);
}
});
});
initialize();
drop();
}
function addMarker() {
console.log('add marker function');
markers.push(new google.maps.Marker({
position: locations[iterator],
map: map,
draggable: false,
animation: google.maps.Animation.DROP
}));
iterator++;
}
function drop()
{
console.log(locations.length);
for (var i = 0; i < locations.length; i++) {
setTimeout(function() {
addMarker();
}, i * 200);
}
}
getPartnerLocations();
geocode is an asynchronous function.
The callback doesn't execute until some time after you call drop.
Therefore, when you call drop, the array is still empty.
You need to call initialize and drop after the last AJAX call replies, in the geocode callback.
I had the following HTML page rendering to use the Google Maps API. This has been running for about two months and all the sudden just stopped working. I am trying to get the point with the getLatLng function and it appears to be returning null everytime. Has anyone experienced a similar issue or see anything wrong here? Any help is appreciated.
Using Version 2 of the API. ("v=2")
var map = null;
var geocoder = null;
var marker;
var g_address = "1 Yawkey Way Boston MA";
var toggleState = 0;
var toggleStateDir = 0;
var mapDir;
var gDir;
var geocoderDir = null;
var markerDir;
var g_addressDir = "100 Commonwealth Ave Boston MA";
var panorama;
var currentYaw = 180;
var currentPitch = 0;
var currentZoom = 0;
function initialize()
{
if (GBrowserIsCompatible())
{
// Map
document.getElementById("address").value = g_address;
document.getElementById("addressDir").value = g_addressDir;
map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
map.addControl(new GLargeMapControl3D());
// Street View
geocoder = new GClientGeocoder();
panorama = new GStreetviewPanorama(document.getElementById("pano"));
// Directions
mapDir = new GMap2(document.getElementById("map_canvas_dir"));
gDir = new GDirections(mapDir, document.getElementById("directions"));
mapDir.addControl(new GMapTypeControl());
mapDir.addControl(new GScaleControl());
mapDir.addControl(new GLargeMapControl3D());
// Traffic overlay
map.setUIToDefault();
var trafficOptions = { incidents: true };
trafficInfo = new GTrafficOverlay(trafficOptions);
mapDir.setUIToDefault();
var trafficOptionsDir = { incidents: true };
trafficInfoDir = new GTrafficOverlay(trafficOptionsDir);
showAddress(g_address, g_addressDir);
}
}
function showAddress(address, addressDir)
{
if (geocoder)
{
geocoder.getLatLng(address,
function(point) {
if (!point) {
alert(address + " not found" + response.Status.code);
}
else {
// Map
g_address = address
map.setCenter(point, 15);
marker = new GMarker(point);
map.addOverlay(marker);
// Street View
document.getElementById("lat").value = point.y;
document.getElementById("long").value = point.x;
document.getElementById("pano").removeAttribute("pano");
panorama.setLocationAndPOV(new GLatLng(point.y, point.x), { yaw: currentYaw, pitch: currentPitch, zoom: currentZoom });
// Directions
gDir.load("from: " + addressDir + " to: " + address, { "locale": "en_US" });
}
}
);
}
}
There's nothing wrong with that code. It works perfectly for me.
Unfortunately, .getLatLng() doesn't return an error code when it fails, and this line will crash when .getLatLng returns nothing:
alert(address + " not found" + response.Status.code);
I can't guess whether there's a problem with your API key (error 610) or if you've been blocked for making too many geocode requests (error 620). I strongly suspect that it will be one of those two because any other error code would be expected to cause the code to fail when I try it.
Try changing your (!point) code to
if (!point) {
geocoder.getLocations(address, function(response) {
alert(address + " not found: " + response.Status.code);
});
}
which uses .getLocations() on the same address and displays the error code.