I am working on an application and need to convert an address supplied by user to lat lng and update a google map. I am using angular js version 1.0.0 Problem is in firefox i keep getting a too much recursion error.
app.controller("BasicMapController", function($scope, $timeout){
.......
angular.extend($scope, {
.......
checking_address: false// curently trying to get lat long from address
});
......
I had to create an ngBlur directive since 1.0.0 didn't have it and upgrading is not an option since too much other code breaks.
app.directive('ngBlur', function() {
return function( scope, elem, attrs ) {
elem.bind('blur', function() {
scope.$apply(attrs.ngBlur);
});
};
});
On my page i add ng-blur="onblur_()" to the relevant text area and then in my controller i define the relevant function:
$scope.onblur_ = function ($event) {
if ($scope.checking_address)
return;
var map_scope = angular.element($('.google-map')).scope();
var address = document.getElementById("id_address").value;
if ( !! !address)
return;
$scope.checking_address = true;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map_scope.map._instance.panTo(results[0].geometry.location);
if ($scope.markers[0] == undefined) {
$scope.markers[0] = new google.maps.Marker({
map: map_scope.map._instance,
position: results[0].geometry.location
});
} else
$scope.markers[0].setPosition(results[0].geometry.location);
}
$scope.checking_address = false;
});
}
The code works fine in Opera and Chromium. Any ideas on what could be wrong or how i could get around the problem?
Related
I work as an intern with Ruby on Rails and yesterday I had to do something with Javascript (my javascript skills ARE AWFUL, I DON'T EVEN HAVE SKILLS with IT).
I implemented current location feature in a project, but I'd like to do it another way... the thig is kinda done, take a look:
function geolocationSuccess(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var geocoder = new google.maps.Geocoder();
var latlng = {lat: latitude, lng: longitude};
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
if (results[0]){
var user_address = results[0].formatted_address;
document.getElementById("current_location").innerHTML = user_address;
}else {
console.log('No results found for these coords.');
}
}else {
console.log('Geocoder failed due to: ' + status);
}
});
}
function geolocationError() {
console.log("please enable location for this feature to work!");
}
$(document).on("ready page:ready", function() {
$("#current-location").on("click", function(event) {
event.preventDefault();
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
} else {
alert("Geolocation not supported!");
}
});
});
All right, I know it all happens when I click the button with Id="current-location", but I'd like it to happen automatically when the page loads, how can I do it?
Simply insert the code you want executed inside of a $(document).ready( block:
$(document).ready(function() {
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(geolocationSuccess, geolocationError);
} else {
alert("Geolocation not supported!");
}
});
On a side note, I would recommend not naming a function variable event since event is a keyword. The standard convention for passing event to a function is to use e. For example:
$('#someId').on('click', function(e) {
e.preventDefault();
//do something
});
I'm developing a website using Wordpress and I'm using a theme that allows to insert custom post called "Property"; this features is handled inside a custom page template. Inside this page I can add the address of the property, which has the autocomplete geocoder suggestion. Here is the code:
this.initAutoComplete = function(){
var addressField = this.container.find('.goto-address-button').val();
if (!addressField) return null;
var that = thisMapField;
$('#' + addressField).autocomplete({
source: function(request, response) {
// TODO: add 'region' option, to help bias geocoder.
that.geocoder.geocode( {'address': request.term }, function(results, status) {
//$('#city').val(results.formatted_address);
response($.map(results, function(item) {
$('#city').val(item.formatted_address);
return {
label: item.formatted_address,
value: item.formatted_address,
latitude: item.geometry.location.lat(),
longitude: item.geometry.location.lng()
};
}));
});
},
select: function(event, ui) {
that.container.find(".map-coordinate").val(ui.item.latitude + ',' + ui.item.longitude);
var location = new window.google.maps.LatLng(ui.item.latitude, ui.item.longitude);
that.map.setCenter(location);
// Drop the Marker
setTimeout(function(){
that.marker.setValues({
position: location,
animation: window.google.maps.Animation.DROP
});
}, 1500);
}
});
}
When an address is clicked, the maps draw a maker with the coordinates received. I would like to extract the city from the address clicked and put that value on another input field. How can I do that? Thanks!
looking at documentation
you need to access address_components and look for type locality, political, so something like this:
var city = '';
item.address_components.map(function(e){
if(e.types.indexOf('locality') !== -1 &&
e.types.indexOf('political') !== -1) {
city = e.long_name;
}
});
$('#city').val(city);
The goal
Reuse already loaded JavaScript correctly.
The problem
I'm generating a map dynamically using Google Maps API V3 and I need to reuse it. How?
The scenario
On Index.html, there's the following script:
var gMapsLoaded = false;
window.gMapsCallback = function () {
gMapsLoaded = true;
$(window).trigger('gMapsLoaded');
}
window.loadGoogleMaps = function () {
if (gMapsLoaded) return window.gMapsCallback();
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
"http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0]
|| document.documentElement).appendChild(script_tag);
}
When I click on some button to show the map, my app invokes this script:
[...]
var geocoder;
var map;
var address = context.address();
function initialize() {
var mapDiv = document.getElementById("map_canvas");
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 15,
center: latlng,
mapTypeControl: true,
mapTypeControlOptions:
{ style: google.maps.MapTypeControlStyle.DROPDOWN_MENU },
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(mapDiv, myOptions);
if (geocoder) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
map.setCenter(results[0].geometry.location);
var infowindow = new google.maps.InfoWindow(
{
content: '<b>' + address + '</b>',
size: new google.maps.Size(150, 50)
});
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map,
title: address
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
} else {
alert("No results found");
}
} else {
alert
("Geocode was not successful
for the following reason: " + status);
}
});
}
gMapsLoaded = false;
}
$(window).on('gMapsLoaded', initialize);
window.loadGoogleMaps();
As you can see, the application is always calling the loadGoogleMaps(); function that calls the external .js file. If I click in the 5 different maps, I get 5 scripts with the same proposal.
Someone have any idea to solve this?
Duplicated question?
Yes, I think that the essence of the question is duplicated, but the nucleus isn't.
As you can see, the application is always calling the
loadGoogleMaps(); function that calls the external .js file. If I
click in the 5 different maps, I get 5 scripts with the same proposal.
That is incorrect. After the first time it completely loads, the if statement on the first line will return early, preventing you from including it multiple times.
There's nothing wrong with the way that's written.
jsFiddle
var gMapsLoaded = false;
window.gMapsCallback = function () {
gMapsLoaded = true;
$(window).trigger('gMapsLoaded');
}
window.loadGoogleMaps = function () {
if (gMapsLoaded) return window.gMapsCallback();
console.log('Generating new script tag');
var script_tag = document.createElement('script');
script_tag.setAttribute("type", "text/javascript");
script_tag.setAttribute("src",
"http://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
(document.getElementsByTagName("head")[0]
|| document.documentElement).appendChild(script_tag);
}
$(window).on("gMapsLoaded",function(){
console.log("gMapsLoaded");
});
$(function(){
$("button").on("click",window.loadGoogleMaps);
});
Now, if you were to click it 5 times really fast when it isn't already loaded, it could potentially load it multiple times. You should call that function on it's own before a click event would normally happen to prevent that.
Update:
At the end of your initialize() method, you're using gMapsLoaded = false; which causes the above code to once again request a new script tag. Simply remove/comment out that line.
This is my first JavaScript I have tried to put together but I am not having a lot of luck.
This is what the script should do: Geocode an address either by clicking on an autosuggested location or by clicking search button if we do not have the result already from clicking autosuggestion. Then submit the form.
I am not having much luck, it seems I have mucked up my bracketing on the script because no matter what I do it complains about exceptions.
This is my code:
geocode();
// SET COOKIE FOR TESTING PURPOSES
$.cookie("country", "US");
// GEOCODE FUNCTION
function geocode() {
var coded = false;
var input = document.getElementById('loc');
var options = {
types: ['geocode']
};
var country_code = $.cookie('country');
if (country_code) {
options.componentRestrictions = {
'country': country_code
};
}
var autocomplete = new google.maps.places.Autocomplete(input, options);
google.maps.event.addListener(autocomplete, 'place_changed', function() {
processLocation();
});
// ON SUBMIT - WORK OUT IF WE ALREADY HAVE THE RESULTS FROM AUTOCOMPLETE FUNCTION
$('#searchform').on('submit', function(e) {
e.preventDefault();
if(coded = false;) {
processLocation();
}
else {
$('#searchform').submit();
}
});
// CHECK TO SEE IF INPUT HAS CHANGED SINCE BEING GEOCODED
// IF "CODED" VAR IS FALSE THEN WE WILL GEOCODE WHEN SEARCH BUTTON HIT
$("#loc").bind("change paste keyup", function() {
var coded = false;
});
};
// GEOCODE THE LOCATION
function processLocation(){
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('loc').value;
$('#searchform input[type="submit"]').attr('disabled', true);
geocoder.geocode({
'address': address
},
// RESULTS - STORE COORDINATES IN FIELDS OR ERROR IF NOT SUCCESSFUL
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var coded = true;
$('#lat').val(results[0].geometry.location.lat());
$('#lng').val(results[0].geometry.location.lng());
} else {
var coded = false;
$('#searchform input[type="submit"]').attr('disabled', false);
alert("We couldn't find this location")
}
});
}
Where have I gone wrong?
PS: Because this is my first script, I am happy to receive feedback if I have made any poor choices in the design of it. I really want to make my first script as cleanly coded as possible.
There is an syntax error
if(coded = false;) {
should be
if(coded == false) {
Checking the console would have told you such a thing and also the place WHERE the error occured.... Here's your fixed fiddle
I don't know why the r1 variable is undefined.
The 'latLng': mEvent.latLng thing is working OK on other functions...
<!-- API V3 --> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
....
.....
....
google.maps.event.addListener(map, 'click', function(mEvent) {
var geo1 = new google.maps.Geocoder();
geo1.geocode( { 'latLng': mEvent.latLng }, function(results, status) {
if ( status == google.maps.GeocoderStatus.OK )
{
var r1 = results[0].formatted_address;
}
else
{
var r1 = '?';
}
});
//do things with mEvent.latLng and r1...
Variable r1 is most probably undefined because it's out of scope. You need to move it's declaration up a bit. E.g.:
google.maps.event.addListener(map, 'click', function(mEvent) {
var geo1 = new google.maps.Geocoder();
var r1;
geo1.geocode( { 'latLng': mEvent.latLng }, function(results, status) {
if ( status == google.maps.GeocoderStatus.OK )
{
r1 = results[0].formatted_address;
}
else
{
r1 = '?';
}
});
//do things with mEvent.latLng and r1...
If you still find some problem use Firebug (in Firefox) or built in debuggers in other browsers. You can insert "debugger;" keyword to stop at some line when a debugger is active. You will then be able to check what variables are available.