I have a map and search-box instantiated and dropping a marker after search is completed. This is working properly, however, I want to query the places services to get places nearby where my marker is dropped and I am getting an error that when running: google.maps.places.PlacesService(map) Uncaught TypeError: undefined is not a function...
Below is some relevant code
In my Angular.module.config:
uiGmapGoogleMapApiProvider.configure({
v: '3.17',
libraries: 'places'
});
In my maps controller:
1) callback when loaded
uiGmapGoogleMapApi.then(function(maps) {
$scope.googleMapsObject = maps;
});
2) setup the event handler to create the marker
$scope.searchbox = {
events: {
places_changed: placesChangedHandler
}
}
3) handle when places are changed, set the marker for lat, and (LAST LINE IS THE PROBLEM) query for the name of the place.
function placesChangedHandler(searchBox) {
var lat = searchBox.getPlaces()[0].geometry.location.k;
var lgn = searchBox.getPlaces()[0].geometry.location.C;
var center = { latitude: lat , longitude: lgn };
$scope.address = searchBox.getPlaces()[0].adr_address;
$scope.map = {
center: center, zoom: 15
};
setMarker(center);
var service = new google.maps.places.PlacesService($scope.googleMapsObject);
// service.nearbySearch(request, callback);
}
The error is on that second to last line. (also, is there a cleaner way to get to those variables?)
Thanks in advance for your help!
I faced the same problem recently and it took time to understand what is wrong because I'm new to angular (to be honest I'm new to Java Script;) )
In your controller you need add $window dependency to access global object google. Here is how it can look like:
.controller('mapCtrl', ['$scope', '$window', 'uiGmapGoogleMapApi'
, function($scope, $window, GoogleMapApi) {
GoogleMapApi.then(function(map) {
$scope.googleVersion = map.version;
$scope.map = { center: { latitude: 59.9500, longitude: 10.7500 }, zoom: 11 };
$scope.googleMapsObject = map
var service = new $window.google.maps.places.PlacesService($scope.googleMapsObject);
});
}])
I think the issue is you are trying to load the places service on the "maps" returned value which is the google.maps object.
so:
$scope.googleMapsObject == google.maps
what you need is to either use the markers directive (which I havent tried yet) or go on the actual map object for your map which you can get from the tilesLoaded event.
$scope.map = {
events: {
tilesloaded: function (map) {
$scope.$apply(function () {
$scope.actualMapObj = map;
$log.info('this is the map instance', map);
});
}
}
}
tilesLoaded from faq: http://angular-ui.github.io/angular-google-maps/#!/faq
After you initialize it with 'places' as library you should have the places property in the api parameter
uiGmapGoogleMapApi.then(function(maps) {
maps.places.PlacesService() // -> here you can search for something
});
Related
I'm trying to use angular-leaflet-directive with Websocket, though I'm able to integrate successfully, the positions of the markers are not getting updated dynamically. However The positions of map gets updated if I move mouse over the map but doesn't get updated when the lat-lng value changes.
Below is code snippet of module.
$scope.markers = {};
angular.extend($scope, {
bounds : $scope.bounds,
center : {},
kppaths : {},
events: {
markers:{
enable: [ 'move' ]
}
}
});
$stomp.setDebug(function(args) {
$log.info(args);
});
$scope.startWS = function() {
var connectionHeaders = {};
// Connect
$stomp.connect("/kp-ws").then(function(frame){
$log.info("connected to server")
$stomp.send('/app/start', {});
// Subscribe for message
$scope.subscription = $stomp.subscribe('/topic/kp', function(
data, headers, res) {
angular.forEach(data, function(k,v){
$scope.markers[k.markerId].lat = k.lat;
$scope.markers[k.markerId].lng = k.lng;
});
});
});
};
$scope.stopWS = function() {
$stomp.send('/app/stop', {});
$scope.subscription.unsubscribe();
$stomp.disconnect();
};
$scope.$on("leafletDirectiveMarker.move", function(event, args){
$log.info(args.model.lat);
});
} ]);
The html file
<div class="card-block">
<leaflet bounds="bounds" geojson="geojson" lf-center="center"
paths="kppaths" markers="markers" event-broadcast="events" width="100%" height="480px"></leaflet>
</div>
Is I'm missing something, Please let me know or suggest how to fix this issue?
The possible workaround I found is:
leafletData.getMap().then(function (map) {
$timeout(function() {map.invalidateSize()});
});
basically, once the map is invalidated, it updates markers' position. Although not perfect, considering some performance issues, the workaround at least solves the main issue.
I'm trying to show different maps in different views but charging 1 on 1 map view, switch to another map not load, there is no mistake to launch the browser so I could not decide because I can not keep showing other maps. I'm doing as follows:
$scope.cargarUbicacion = function () {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
latitud_actual = position.coords.latitude;
longitud_actual = position.coords.longitude;
console.log(latitud_actual);
console.log(longitud_actual);
var mapOptions = {
center: new google.maps.LatLng(latitud_actual, longitud_actual),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scrollwheel: false
};
map = new google.maps.Map(document.getElementById("mapa_ubicacion"), mapOptions);
$scope.setMarker(map, new google.maps.LatLng(latitud_actual, longitud_actual), 'Yo', '');
});
}
}
$scope.setMarker = function(map, position, title, content) {
var marker;
var markerOptions = {
position: position,
map: map,
title: title,
icon: 'http://maps.google.com/mapfiles/ms/icons/green-dot.png'
};
marker = new google.maps.Marker(markerOptions);
markers.push(marker); // add marker to array
google.maps.event.addListener(marker, 'click', function () {
// close window if not undefined
if (infoWindow !== void 0) {
infoWindow.close();
}
// create new window
var infoWindowOptions = {
content: content
};
infoWindow = new google.maps.InfoWindow(infoWindowOptions);
infoWindow.open(map, marker);
});
}
I am using this code in multiple controllers, my idea is encapsulated and can occupy the same code 1 time in several views. Whenever I change the id map to avoid that problem, thinking that this was the cause that did not load the map.
Any idea how to do what I need or that is failing to load maps?
Thank you.
I personnaly do the following :
The code taht you want to reuse put it into a global variable such as :
Then into your control, you can extend it with this mapExtend
global.MapExtend = function($scope, $rootScope, leafletData) {
// ... all your functions to reuse
};
// In your main controler, extend it with your map capabilities with angular.extend
angular.extend(myCtrl, new MapExtend($scope, $rootScope, leafletData));
I'm trying to display markers on a map, but I am running in to difficulty, I'm not too skilled in the use of callbacks, can someone help me out thanks? I want multiple markers to show where different games are.
I'm using a rest api to retrieve the game details from the db, and I know this works, it's just after I retrieve them I can no longer access the data that has just been retrieved.
I am using ionic (Angular) and I am sure there is probably a better way of doing this. What is the best way to use a loop? If anyone could point out how I could improve my code. Here is what my controller for the map looks like
.controller('MapController', function($scope, $ionicLoading, gameFactory) {
$scope.initialise = function() {
...//set up map
});
$scope.map = map;
};
$scope.showGameMarkers = function() {
var map = document.getElementById("map");
gameFactory.getGames().success(function(data) {
//at this stage the data variable contains the details of my game
angular.forEach(data, function(key, data) {
//now data is empty
var latLng = new google.maps.LatLng(data.locationLatitude, data.locationLongitude);
console.log("latlang = "+latLng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
title: data.locationName,
setMap : map
});
});
}).error(function(data) {
console.log("no games");
});
};
google.maps.event.addDomListener(document.getElementById("map"), 'load', $scope.initialise());
google.maps.event.addDomListener(document.getElementById("map"), 'load', $scope.showGameMarkers());
});
Thank you in advance!
It looks like you might have your key and data parameters reversed in your forEach loop. According to https://docs.angularjs.org/api/ng/function/angular.forEach it should be
angular.forEach(values, function(value, key) {
...
}
The initial request url is http://localhost/#/map?lat=33.73060000952102&lng=-117.12635126323244
In my project I'm using Google Maps Autocomplete Service which autopopulates the text field with address predictions and upon select an address the map is centered to that location. My place_changed event listener is fired successfully and my controllers setLocation function is called successfully. However, the URL in the address bar is NOT updated with the new lat and lng param values.
If I call $scope.getProjectsByCenter() from an ng-click in the html it works. Somehow event chain in place_changed conflicts with $location.search.
Anyone have any thoughts as to why?
angular: app.js
var app = angular.module('projectmapsApp', []);
app.controller('MainMapController', function($scope,$location){
$scope.setLocation = function(lat,lng){
$location.search('lat',lat);
$location.search('lng',lng);
console.log($location.search()); //This logs an object with the new lat and lng
};
$scope.getProjectsByCenter = function(){
var center = getProjectsByCenter();
$scope.setLocation(center.lat(),center.lng());
};
});
vanilla: map.js
function initializeMap() {
var map = new google.maps.Map(document.getElementById("map-canvas"), {
center: {lat: 33.868670, lng: -117.796783}
});
var input = document.getElementById('place-search');
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.addListener('place_changed', function() {
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
var lat = place.geometry.location.lat();
var lng = place.geometry.location.lng();
angular.element('#MainMapController').scope().setLocation(lat,lng);
};
};
Found the answer. $apply()
My setLocation now looks like this:
$scope.setLocation = function(lat,lng){
$location.search('lat',lat);
$location.search('lng',lng);
$scope.$apply();
};
Great article here: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
I am using
http://jsfiddle.net/xSPAA/371/
//Add the requried module 'angular-ui' as a dependency
angular.module('maptesting', ['ui.map','ui.event']);
function MapCtrl($scope) {
var ll = new google.maps.LatLng(45, -73);
$scope.mapOptions = {
center: ll,
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//Markers should be added after map is loaded
$scope.onMapIdle = function() {
if ($scope.myMarkers === undefined){
var marker = new google.maps.Marker({
map: $scope.myMap,
position: ll
});
$scope.myMarkers = [marker, ];
}
};
$scope.markerClicked = function(m) {
window.alert("clicked");
};
}
plunker to show google map. I need to show a specific location map that a user will enter into a text box.
How can I do it?
Do I need to use Geo Location API?
Can any one give sample code or plunker?
Below is the working example :
http://www.victorshi.com/blog/post/Use-Geolocation-API-with-Angularjs
Example
Also check below url:
http://www.benfarrell.com/2013/11/05/some-geolocation-and-google-mapping-services-in-angularjs/
Google Location Service
http://jsfiddle.net/mrajcok/pEq6X/
directive 'googlePlaces'