Google Maps Issue Cannot call method 'apply' of undefined? - javascript

I have searched all over google for a solution however this seems a new one? I am trying to implement google maps API on a site however I keep getting the following error:
Uncaught TypeError: Cannot call method 'apply' of undefined
My JS is as follows:
var map;
function initialize(location) {
var mapDiv = document.getElementById('map-canvas');
var latLng;
if (location == 0) {
latLng = new google.maps.LatLng(52.066356, 1.102388);
}
else if (location == 1) {
latLng = new google.maps.LatLng(52.672492, 1.232196);
}
else if (location == 2) {
latLng = new google.maps.LatLng(52.207607, 0.123017);
}
map = new google.maps.Map(mapDiv, {
center: latLng,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
google.maps.event.addDomListener(map, 'tilesloaded', addMarker(location));
}
function addMarker(location) {
var latLng;
if (location == 0) {
latLng = new google.maps.LatLng(52.066703, 1.113573);
}
else if (location == 1) {
latLng = new google.maps.LatLng(52.672492, 1.232196);
}
else if (location == 2) {
latLng = new google.maps.LatLng(52.207607, 0.123017);
}
var marker = new google.maps.Marker({
position: latLng,
map: map
});
}
$(document).ready(function () {
initialize(0);
});

In this line
google.maps.event.addDomListener(map, 'tilesloaded', addMarker(location));
You're calling the function addMarker instead of passing it as a function reference. Therefore, addMarker is getting executed before map is defined. Try changing that line to:
google.maps.event.addDomListener(map, 'tilesloaded', function() {addMarker(location)});

The problem is you're invoking the function addMarker which you should be supplying a callback. Change your call to the following
google.maps.event.addDomListener(map, 'tilesloaded', function() { addMarker(location) });
Right now you're instead directly invoking addMarker which returns no value. This means you're effectively passing undefined to the API and the google library is hitting the error attempting to invoke your callback

Related

JavaScript Google Maps API How to Store Location lat/long to Global Variable

I'm new to JavaScript, and am looking to implement the code provided by Google for putting a marker at your location. However, I'd like to take the location data and use it outside of the "getCurrentPosition" block.
My first pass was to instantiate an Object with lat and long as properties outside of the block and have this as a parameter of the function inside getCurrentPosition:
function initMap() {
var pos = {
lat: 42.1,
lng: -74.1
};
var map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 42, lng: -74},
zoom: 6
});
var infoWindow = new google.maps.InfoWindow({map: map});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position, pos) {
pos.lat = position.coords.latitude;
pos.lng = position.coords.longitude;
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
var marker = new google.maps.Marker({
position: pos,
map: map,
title: 'Release Source'
});
}
The effect of this is that the marker will be at the position specified when the object is instantiated. These are placeholder values, as my current location is several states away.
'pos.lat = position.coords.latitude' and 'pos.lng = position.coords.longitude' are not overwriting the property values as set when the global "pos" object was instantiated.
The map is not centered on my current position, but based on the placeholder lat and long values originally assigned to "pos" when instantiated.
When I change to "navigator.geolocation.getCurrentPosition(function(position) {
...
}",
this removes reference to the global "pos" variable inside of the "getCurrentPosition" block. It appears a local variable named "pos" is created.
The local instance of "pos" inside of the block will have its lat and long assigned based on my current location. The map is then centered around my current location, as per instruction in the block.
The marker will, however, be shown at the original lat long that were assigned as placeholder values when the global variable "pos" was instantiated.
Please let me know how I can get the current lat/long values data outside of the "getCurrentPosition" block and into the global "pos" object.
The getCurrentPosition method is defined as (from the documentation):
navigator.geolocation.getCurrentPosition(success[, error[, options]])
Parameters
success - A callback function that takes a Position object as its sole input parameter.
error - Optional - An optional callback function that takes a PositionError object as its sole input parameter.
options - Optional - An optional PositionOptions object.
The way you are using it causes a local pos variable to be created (with the value of null).
function(position, pos) {
Just create the function signature with a single argument:
function(position) {
code snippet:
function initMap() {
var infoWindow = new google.maps.InfoWindow();
var pos = {
lat: 42.1,
lng: -74.1
};
var map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 42,
lng: -74
},
zoom: 6
});
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
pos.lat = position.coords.latitude;
pos.lng = position.coords.longitude;
map.setCenter(pos);
var marker = new google.maps.Marker({
position: pos,
map: map,
title: 'Release Source'
});
}, function() {
handleLocationError(true, infoWindow, map.getCenter(), map);
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter(), map);
}
function handleLocationError(input, infoWindow, center, map) {
infoWindow.setContent("ERROR: " + input);
infoWindow.setPosition(center);
infoWindow.open(map);
}
}
google.maps.event.addDomListener(window, 'load', initMap);
html,
body,
#map {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map"></div>
proof of concept fiddle
If I understand you right... this should work. I've added a global variable called the_position which gets assigned a new value on each getCurrentPosition call.
var the_position = { // ADDED THIS
lat: 0,
lng: 0
};
function initMap() {
... all your current code
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
the_position.lat = position.coords.latitude; // ADDED THIS
the_position.lng = position.coords.longitude; // ADDED THIS
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
}
... all your current code
}
Then when you want to retrieve the latest lat/lng just use...
// The Lat/Lng
var lat = the_position.lat;
var lng = the_position.lng;

Google maps, passing "map" to a different event

I have 2 different events, please correct me if i am doing this wrong,
//initializing the map
google.maps.event.addDomListener(window, 'load', initialize);
//initializing the markers
google.maps.event.addListener(map, 'idle', showMarkers);
The first event is to initialize the map (set it up), the second event is for querying the database for new markers when the current map bounds change (not functional yet)
Since I have defined "map" inside the initialize function, how can I access it outside the function and pass it to the second event? As you can see i have declared it before the functions as a global variable but it is still undefined as the event argument, i have been stuck on this for days
var map;
function initialize(){
//defining map options
var mapLatlng = new google.maps.LatLng(37.09024, -100.712891);
var mapOptions = {
zoom: 4,
center: mapLatlng
}
//defining the map itself
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function showMarkers(){
Parse.initialize("X","X");
var query = new Parse.Query("business_and_reviews");
var results = new Parse.Object("business_and_reviews");
query.equalTo("name","McDonalds");
query.find({
success: function(results) {
console.log(results);
for (var i = 0; i < results.length; i++) {
var object = results[i];
}
var lat = (object["attributes"]["lat"]);
var lng = (object["attributes"]["lng"]);
console.log(lat);
console.log(lng);
//adding the marker from the query
var marker = new google.maps.Marker({
position: mapLatlong,
map: map,
title: 'Hello World!'
});
},
error: function(object, error) {
}
});
}
//initializing the map
google.maps.event.addDomListener(window, 'load', initialize);
//initializing the markers
google.maps.event.addListener(map, 'idle', showMarkers);
For the second event "map" is undefined
SOlved it! put the idle event listener inside the initialize function and it works like a charm! I guess initilize isn't to initialize the page initially but runs constantly

Google place search markers not showing on map

I'm coding a demo of how I want a future search function to work. I want to query google on an address or area and return the area bounds as well as nearby places. To do this, I am using places autocomplete, geocode, and places search.
So far I am successfully getting predicted search queries resulting in the bounds being drawn as a rectangle on my map. However, when I try to implement markers for the place search result no markers are appearing on my map. I know the search is working because putting an alert in the createMarker function on each location returns several lat/lng's that coincide with my area.
I suspect that maybe the map object is not being passed to my createMarker function, but I am kind of a noob when it comes to Javascript. I tried passing an additional parameter but it didn't do much.
It should be noted that I am able to create a marker within the initialize function, when I attempt to just create one static marker.
EDIT: I have removed the type parameter for the place search request, but the code doesn't work even with the parameter ['store'].
var map;
var infowindow;
function initialize() {
var view_lat = document.getElementById('view_lat').value;
var view_lng = document.getElementById('view_lng').value;
var focus = new google.maps.LatLng(view_lat,view_lng);
var swlat = document.getElementById('swlat').value;
var swlng = document.getElementById('swlng').value;
var nelat = document.getElementById('nelat').value;
var nelng = document.getElementById('nelng').value;
var map_canvas = document.getElementById('map-canvas_embed');
var map_options = {
center: new google.maps.LatLng(parseFloat(view_lat), view_lng),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var mysw = new google.maps.LatLng(swlat,swlng)
var map = new google.maps.Map(map_canvas, map_options)
var rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: new google.maps.LatLngBounds(
new google.maps.LatLng(swlat, swlng),
new google.maps.LatLng(nelat, nelng))
});
var request = {
location: focus,
radius: 500
};
var place_search = new google.maps.places.PlacesService(map);
place_search.nearbySearch(request,callback)
}
Handles the result from google places search
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
position: place.geometry.location
});
marker.setMap(map);
}
Autocomplete variables
var input = document.getElementById('location');
var options = {
componentRestrictions: {country: 'se'},
types: ['geocode']
}
var searchform = document.getElementById('searchform');
var place;
var autocomplete = new google.maps.places.Autocomplete(input, options);
Add listener to detect autocomplete selection
google.maps.event.addListener(autocomplete, 'place_changed', function () {
place = autocomplete.getPlace();
//console.log(place);
});
Add listener to search (This function isn't working, hence my work around in the initialize function)
searchform.addEventListener("submit", function() {
var newlatlong = new google.maps.LatLng(place.geometry.location.lat(),place.geometry.location.lng());
map.setCenter(newlatlong);
marker.setPosition(newlatlong);
map.setZoom(12);
google.maps.event.trigger(map, 'resize');
});
Reset the inpout box on click
input.addEventListener('click', function(){
input.value = "";
});
Call the initialize function
google.maps.event.addDomListener(window, 'load', initialize);
Indeed it looks like a problem of JavaScript's scope.
Consider these lines of your code:
function initialize() {
//...
var map = new google.maps.Map(map_canvas, map_options)
//...
}
Declaring map inside the initialize function makes your map variable unreachable out of your initialize function.
So when you try to reach it in your searchform, map.setCenter() will show in your console that map is undefined.
You could solve your issue in several ways.
declare map at the beginning of your script (before initialize is executed, anyways)
declare the searchform.addEventListener("submit", function(){}) inside your initialize() function and use it before initialize() ends its execution.

TypeError: map is undefined google api

I have been referencing a found tutorial and have stumbled upon an error using the google maps api. I am getting and error that telling me that a variable is not defined when in fact it is. I am not exactly sure what the problem is.. Please help.
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=true">
</script>
<script type="text/javascript">
var map;
var service;
function handleSearchResults (results, status)
{
console.log(results);
}
function performSearch ()
{
var request = {
bounds: map.getBounds(),
name: "McDonald's" // within the bounds find the given name
}
service.nearbySearch(request, handleSearchResults);
}
function initialize (location) //initializing geolocation function
{
console.log(location);
var currentLocation = new google.maps.LatLng(location.coords.latitude, location.coords.longitude)
var mapOptions = {
center: currentLocation,
zoom: 13
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
// To add the marker to the map, use the 'map' property
var marker = new google.maps.Marker({
position: currentLocation,
map: map // referencing google map from variable map above
});
service = new google.maps.places.PlacesService(map);
// wait until map bounds are initialized before performing search
google.maps.event.addListenerOnce(map, 'bounds_changed', performSearch);
}
$( document ).ready(function()
{
navigator.geolocation.getCurrentPosition(initialize);
});
</script>
</html>
It looks like you're running into scoping issues with that map variable since you're calling the initialize function from within the scope of the $(document.ready() callback. I made some adjustments to it in the jsfiddle below. Does that fix the issue?
jsfiddle
function handleSearchResults (results, status)
{
console.log(results);
}
function performSearch ()
{
var request = {
bounds: map.getBounds(),
name: "McDonald's" // within the bounds find the given name
}
service.nearbySearch(request, handleSearchResults);
}
function initialize (location) //initializing geolocation function
{
console.log(location);
var currentLocation = new google.maps.LatLng(location.coords.latitude, location.coords.longitude)
var mapOptions = {
center: currentLocation,
zoom: 13
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
// To add the marker to the map, use the 'map' property
var marker = new google.maps.Marker({
position: currentLocation,
map: map // referencing google map from variable map above
});
service = new google.maps.places.PlacesService(map);
// wait until map bounds are initialized before performing search
google.maps.event.addListenerOnce(map, 'bounds_changed', performSearch);
}
$(document).ready(function() {
var map;
var service;
navigator.geolocation.getCurrentPosition(initialize);
})

Javascript Scope & Geocode [duplicate]

This question already has an answer here:
How to get a javascript lat/lng variable out of a Google Map API function
(1 answer)
Closed 9 years ago.
I've been searching here all day for help with what is likely, just a basic noob javascript mistake.
I'm trying to get the lat/long from an address using google's geocoder glass. However, I can't seem to assign it to a global or even derive it from the object's property (which I would prefer). Basically all I need at this point to to just get the location from the geocoder and everything else should fall in place. See code:
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true&libraries=places"></script>
<script>
var geocoder = new google.maps.Geocoder();
var ListingAddress = '1600 Pennsylvania Ave NW Washington, DC 20500';
var map;
var infowindow;
//var ListingLoc = new google.maps.LatLng(-33.8665433, 151.1956316);
var ListingLatLong;
var ListingLoc;
function initialize() {
geocoder.geocode({
address: ListingAddress
},
function(results){
ListingLatLong = results[0].geometry.location;
ListingLoc = new google.maps.LatLng(ListingLatLong);
});
map = new google.maps.Map(document.getElementById('map_canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: ListingLoc,
zoom: 15
});
var request = {
location: ListingLoc,
radius: 500,
types: ['school']
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, callback);
}
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
AND the markup
<div id="map_canvas" style="width:600px;height:400px;border:none;"></div>
The second argument of geocoder.geocode is a callback function that executes asynchronously. That means that the function will run sometime after the rest of your code. Thus,ListingLatLong is not assigned a value until after you've tried to use it.
Asynchronous execution is the norm for performing network requests in JavaScript. Instead of causing your code to hang by waiting a long time for a network round-trip, you simply dispatch a request and define a listener function to fire when the request completes some time later. That's what is happening here: the function argument to geocoder.geocode is a listener function that fires once the data arrives from Google's geocoding server. geocoder.geocode doesn't run that function, exactly -- it just says, "Okay, JavaScript, here's a function you should run whenever my request completes."
To solve this problem, simply move any code that needs to use the values of results (and/or ListingLatLong) inside the callback function:
geocoder.geocode({
address: ListingAddress
},
function(results){
ListingLatLong = results[0].geometry.location;
ListingLoc = new google.maps.LatLng(ListingLatLong);
// ** note this is inside the callback now **
map = new google.maps.Map(document.getElementById('map_canvas'), {
mapTypeId: google.maps.MapTypeId.ROADMAP,
center: ListingLoc,
zoom: 15
});
// add the rest of your code here, too
// ...
});
(Side note: you should use uppercase variable names only for constructors (e.g., var Person = function(name) { this.name = name; }) and lowercase variable names for instances (e.g., someGuy = new Person("Bob");). When I see the name ListingLatLong, I expect it to be a constructor, but it's not, so I'd suggest using listingLatLong instead.)

Categories