using angular-google-maps to incorporate a google map into an app
I need a command that will run a function ONCE after initial map load is complete
- but only on the initial load, not after each map manipulation
I can't use idle
or tilesloaded
since these are fired after every movement...
The function I want to run needs to get map bounds to pull data off a server on initial page load
- i want this to occur ONCE on initial load, then be a manual function using a refresh map-control
- if i use idle
or tilesloaded
to fire this it will pull server data every time a user moves the map.
Does anyone know how to fire a once off command to get map details (bounds etc) after initial map load ?
I've tried putting maps.getBounds()
in the 2nd promise function but it doesn't work.
Note, I've got a fiddle working here - I just can't chain any more promises after the $scope.map
controls / options etc are defined because they don't return a promise:
The code example in the docs doesn't show how to chain a promise after the $scope.map
is defined.
html
<div class="angular-google-map-container" ng-controller="MainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="map.options" events="map.events" control="googlemap">
</ui-gmap-google-map>
</div>
controller
myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi) {
uiGmapGoogleMapApi
.then(function(maps){
$scope.map = {
center: {
latitude: 37.7749295,
longitude: -122.4194155
},
zoom: 12
events: {
tilesloaded: function (maps, eventName, args) {
myServiceFuntion(maps) // this work fine but fires every time
},
dragend: function (maps, eventName, args) {
myServiceFuntion(maps) // this work fine but fires every time
},
zoom_changed: function (maps, eventName, args) {
myServiceFuntion(maps) // this work fine but fires every time
}
}
}
$scope.bounds = maps.getBounds() // this gives me 'getBounds() not a function'
myServiceFuntion(maps); // this gives an error... ?
return maps; //no promise returned here so no chance to delay the function below
})
.then(function(maps){
//is this where i need to put my function ? doesn't delay on map load since no promise returned...
});
});
Obviously the maps
object returned by the uiGmapGoogleMapApi
promise is completely different to the maps
object returned by events like tilesloaded
etc... quite confusing.
Also, the FAQ only indicates how to use tilesloaded
to get the map instance - which doesn't work for reasons already described.
The 'correct' method I believe is to use the API IsReady
feature by injecting the uiGmapIsReady
service into the controller. See the documentation.
With the uiGmapIsReady
promise it's then possible to pass the map
to a function / service etc with code like:
uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map
.then(function(instances) { // instances is an array object
var maps = instances[0].map; // if only 1 map it's found at index 0 of array
$scope.myOnceOnlyFunction(maps); // pass the map to your function
});
it's also possible to iterate through the instances
array to run functions on each map (if you have more than one map loaded in your page):
uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map
.then(function(instances) { // instances is an array object
angular.forEach(instances, function(value, key) {
var maps = value.map;
$scope.myOnceOnlyFunction(maps); // will apply this function to each map
});
});
so then the whole controller would look like
myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi, uiGmapIsReady) {
uiGmapGoogleMapApi
.then(function(maps){
$scope.googlemap = {};
$scope.map = {
center: {
latitude: 37.7749295,
longitude: -122.4194155
},
zoom: 13,
pan: 1,
options: myAppServices.getMapOptions().mapOptions,
control: {},
events: {
tilesloaded: function (maps, eventName, args) {
},
dragend: function (maps, eventName, args) {
},
zoom_changed: function (maps, eventName, args) {
}
}
};
});
uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map
.then(function(instances) { // instances is an array object
var maps = instances[0].map; // if only 1 map it's found at index 0 of array
$scope.myOnceOnlyFunction(maps); // this function will only be applied on initial map load (once ready)
});
$scope.myOnceOnlyFunction = function(maps){ // this will only be run once on initial load
var center = maps.getCenter(); // examples of 'map' manipulation
var lat = center.lat();
var lng = center.lng();
alert('I\'ll only say this once ! \n Lat : ' + lat + '\n Lng : ' + lng);
};
});
...not sure why this isn't mentioned in the FAQ: 'How do I access the map instance?' - or why using tilesloaded
(which is thought to be unreliable) is suggested instead of idle
or uiGmapIsReady
... ?
Perhaps the FAQ question was really 'how do i access the map on a continual basis' ?