Inject value to module after bootstrap - angularjs

I want to use angular-ui for google maps. From the example, it passes a hard-coded coordinate.
$scope.mapOptions = {
center: new google.maps.LatLng(35.784, -78.670),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
Then use it on the directive.
<div id="map_canvas" ui-map="myMap" class="map" ... ui-options="mapOptions">
</div>
But I need the coordinates to be the user location, to get that, I need to use navigator.geolocation.getCurrentPosition() which I got the coordinate in a callback.
I'm thinking of something like:
navigator.geolocation.getCurrentPosition(function(result) {
angular.bootstrap(myElement, ['myModule']); // I need a way to inject "result" to the module
}, function(error) {
// fallback to default coordinate.
});
Any suggestion?

Add the constant to the module before bootstrapping:
angular.module('myModule', [])
.controller('MyController', function($scope, coordinates){
$scope.coordinates = coordinates;
})
navigator.geolocation.getCurrentPosition(function(result) {
angular.module('myModule').constant('coordinates', result);
angular.bootstrap(document, ['myModule']);
}, function(error) {
// fallback to default coordinate.
});
Demo

Related

Way-points - How can i remove a specific way-point from google maps?

I am making this app with the help of google maps, i am successfully adding waypoints in a route and making a route between them. But on dbclick i remove that way point from the map. Now when i make the route it includes the deleted waypoint too. Because of the fact it does not delete from the waypoint array.
The question is how can i remove a specific waypoint from the waypoint array. I dont have any index of something.
pushing waypoints
/* Whenever a user taps a pin it goes into pinwapypts */
pinwaypts.push({
location: $scope.destination_route,
stopover: true,
});
Add waypoints in map
infowindow.open($scope.map, marker);
$scope.markers.push(marker);
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent($scope.results[0].formatted_address);
infowindow.open($scope.map, this);
});
removing waypoint marker from map
google.maps.event.addListener(marker, 'dblclick', function () {
$scope.markers.pop().setMap(null);
});
Now how can i remove a specific waypoint from its array ?
full code
function getClickLoc(latlng) {
var geocoder = new google.maps.Geocoder;
geocoder.geocode({
'location': latlng
}, function (results, status) {
$scope.results = results;
//console.log(results);
if (status === 'OK') {
if (results[0]) {
$scope.map.setZoom(12);
var marker = new google.maps.Marker({
position: latlng,
map: $scope.map
});
infowindow.setContent(results[0].formatted_address);
$scope.destination_route = latlng;
/* Whenever a user taps a pin it goes into pinwapypts */
pinwaypts.push({
location: latlng,
stopover: true
});
$scope.$apply();
infowindow.open($scope.map, marker);
$scope.markers.push(marker);
google.maps.event.addListener(marker, 'dblclick', function () {
infowindow.setContent($scope.results[0].formatted_address);
infowindow.open($scope.map, this);
});
google.maps.event.addListener(marker, 'dblclick', function () {
$scope.markers.pop().setMap(null);
});
//$ionicLoading.hide();
} else {
window.alert('No results found');
}
} else {
window.alert('Something went wrong, Please try again.');
//window.alert('Geocoder failed due to: ' + status);
}
});
}
Your full code has a lot of missing things, so I gave a best-effort to create a minimal, complete, and verifiable example out of it. This assumes you create a waypoint each time you create a marker. And markers are created via click/tap on the map.
When removing a waypoint from an array, you can get its index using indexOf. So inside your listener for dblclick, you get the index by doing:
var wayptIndex = $scope.pinwaypts.indexOf(waypoint);
and then splicing it by:
$scope.pinwaypts.splice(wayptIndex, 1);
I provided the example code below (Be sure to use your own API KEY) and you'll notice the listener is in a closure. This is so that I can still pass the waypoint variable to it, without it losing scope.
You can also check this jsbin link
P.S.
Your removal of markers is also incorrect. Do not do a pop() as that only removes the last item in the array. If you double click a middle array, it will still remove the last item. I also used indexOf to get the marker's correct index.
Hope this helps and hope you can create minimal and complete examples next time! :)
(function(angular) {
'use strict';
angular
.module('ngApp', [])
.controller('demoController', demoController);
function demoController($scope) {
initMap();
$scope.pinwaypts = [];
$scope.markers = [];
function initMap() {
$scope.map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: -34.397,
lng: 150.644
},
zoom: 8
});
$scope.map.addListener('click', getClickLoc);
}
function getClickLoc(e) {
var latlng = e.latLng;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'location': latlng
}, function(results, status) {
$scope.results = results;
if (status === 'OK') {
if (results[0]) {
var marker = new google.maps.Marker({
position: latlng,
map: $scope.map
});
$scope.map.panTo(latlng);
$scope.map.setZoom(12);
// you did not show how you instantiated your infowindow so I added this
var infowindow = new google.maps.InfoWindow();
infowindow.setContent(results[0].formatted_address);
$scope.markers.push(marker);
$scope.destination_route = latlng;
/* Whenever a user taps a pin it goes into pinwapypts */
var waypoint = {
location: latlng,
stopover: true
};
$scope.pinwaypts.push(waypoint);
// I'm not sure if you still really need this.
$scope.$apply();
infowindow.open($scope.map, marker);
google.maps.event.addListener(marker, 'click', function() {
// This is redundant. You can just open the infowindow on click of the marker // infowindow.setContent($scope.results[0].formatted_address);
infowindow.open($scope.map, this);
});
(function(waypoint, marker) {
google.maps.event.addListener(marker, 'dblclick', function() {
// Pop has an issue. You will only remove the last marker from your array,
// not the specific marker the user is double-clicking.
// $scope.markers.pop().setMap(null);
var markerIndex = $scope.markers.indexOf(marker);
// You don't remove the markers from the array. Just set them to setMap(null)
// removing them will mess up their indeces and this will no long work
// just refresh the markers array on a new request or something
$scope.markers[markerIndex].setMap(null);
// Get the index of the waypoint and this once you remove so that
// it's not included when you do a directions service request
var wayptIndex = $scope.pinwaypts.indexOf(waypoint);
$scope.pinwaypts.splice(wayptIndex, 1);
});
}(waypoint, marker))
} else {
window.alert('No results found');
}
} else {
window.alert('Something went wrong, Please try again.');
}
});
}
}
})(window.angular);
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html,
body,
#view {
height: 100%;
margin: 0;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<!-- BE SURE TO USE YOUR OWN API KEY. This loads the script synchronously and I call initMap manually inside my controller. For demo purposes only. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAZVylT7o5OxdosVfh-IVONHoaA0cpN5VI"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js"></script>
</head>
<body ng-app="ngApp">
<div id="view" ng-controller="demoController">
<div id="map"></div>
</div>
</body>
</html>

Divide google key and angular directive google map into two files

I have created an angularJS directive to call the google maps api. The directive looks like that:
angular.module('sbAdminApp')
.directive('allWash', function () {
return {
templateUrl: 'static/app/scripts/directives/googleMap/allWash.html',
restrict: 'E',
replace: true,
controller: function ($scope, WashService) {
$scope.initMap = new function () {
var locations = [
['Bondi Beach', 52.229676, 21.012228999999934, 4],
['Coogee Beach', 52.14276459999999, 21.02135450000003, 5],
['Cronulla Beach', -34.028249, 151.157507, 3],
['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
['Maroubra Beach', -33.950198, 151.259302, 1]
];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
var marker, i;
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][1], locations[i][2]),
map: map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(locations[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
}
}
}
});
The google also demands to create a key which I actually created and put it into the index.html file, like that:
<script src="http://maps.google.com/maps/api/js?key=AIzaSyD5bgIqM-C7WVWkaGDa0AE2luY-dbF6nBA"
async defer
type="text/javascript"></script>
My html file (allWash.html file which is connected to the directive) looks like:
<script type="text/ng-template" id="allWash.html">
<div>
<div id="map" style="width: 600px; height: 600px;" ng-init="initMap()"></div>
</div>
</script>
When I want to call the diretive at diffrent html page I do <all-wash></all-wash>
The whole code creates a fail:
I think it is connected to the google key which I put into index.html file, but I'm not sure so that I don't know how to solve this issue.
You may refer with this thread. This error might happen if you load the script before the DOM was loaded. Try to move the script to the end of body and check if it works.
Also, it might be due to the map div not being rendered before the javascript runs that needs to access it. Check it here. "You should put your initialization code inside an onload function or at the bottom of your HTML file, just before the tag, so the DOM is completely rendered before it executes (note that the second option is more sensitive to invalid HTML)."

Angular Leaflet Directive Not updating marker position

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.

Google Maps v3 api in routed view doesn't work

Hi guys i have problems trying to run a google map example into a routed view, map is not displayed and no errors are displayed, i read some thing about initialize in a directive, i don't know how to do it, any help will be very apreciated:
app.conf
app.controller( 'viewCtrl', function( $http, $location ) {
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
google.maps.event.addDomListener(window, 'load', initialize);
} );
In my view i have:
<div id="map-canvas"></div>
It worked into my view adding a size to div:
<div id="map-canvas" style="height:200px;width:200px;"></div>
Sry for this questiĆ³n and hoppe thiscan help to others

how to use GooglePlacesServices with angular-google-maps

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
});

Resources