I have a function in Angular that changes the center value for Google Maps when a user clicks on the map. The correct center value is then alerted to the screen but the marker does not change to that position like it should.
Web page: http://alainwebdesign.ca/pl2/#/getLocation
Controller:
.controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams",
function ($scope, $log, GoogleMapApi, $state, $stateParams) {
$log.currentLevel = $log.LEVELS.debug;
center = { latitude: 49.22, longitude: -122.66 }; //default center
alert(JSON.stringify(center));
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events:
{ click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
alert(JSON.stringify(center));
return center;
});
}
}
}
HTML partial/view:
<!--Add ability to input location as address-->
<div style="height: 100%">
<h1>TEST</h1> <!--NOT SHOWING ON PAGE WHICH MEANS THIS IS NOT BEING INVOKED WHEN
URL IS: '/getLocation' like it should-->
<ui-gmap-google-map
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-marker
idKey='1'
events='map.events'
coords='map.center'
>
</ui-gmap-marker>
</ui-gmap-google-map>
<script src='//maps.googleapis.com/maps/api/js?key=AIzaSyD4_0KuPivZyV-1EwNGmBCgLc_Z0o8Dyw8'></script>
</div>
You can directly set $scope.map.center instead of center variable and it will be ok. Here is working click function example:
click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
$scope.map.center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
});
}
Related
I am trying to use ngMaterial in my Angular app and getting the errors: ReferenceError: $event is not defined and TypeError: Cannot read property 'confirm' of undefined. I have looked at the ngMaterial docs and am using the code from this example: https://material.angularjs.org/latest/demo/dialog but can't find what I am doing wrong.
The ReferenceError refers to this line:
$timeout($scope.showConfirm($event), 500);
And the TypeError refers to:
var confirm = $mdDialog.confirm()
Below is my code:
html:
<div style="height: 100%">
<h1>TEST</h1> <!--NOT SHOWING ON PAGE WHICH MEANS THIS IS NOT BEING INVOKED WHEN
URL IS: '/getLocation' like it should-->
<ui-gmap-google-map
class="md-primary md-raised" ng-click="showConfirm($event)"
center='map.center'
zoom='map.zoom'
draggable='map.draggable'
dragging='map.dragging'
refresh='map.refresh'
options='map.options'
events='map.events'
pan='map.pan'>
<ui-gmap-marker
idKey='1'
events='map.events'
coords='map.center'
>
</ui-gmap-marker>
</ui-gmap-google-map>
<script src='//maps.googleapis.com/maps/api/js?key=AIzaSyD4_0KuPivZyV-1EwNGmBCgLc_Z0o8Dyw8'></script>
</div>
Controller:
(function (window, ng) {
ng.module('app', ['uiGmapgoogle-maps', 'ui.router', 'ngMaterial'])
.config(function ($stateProvider) { //had: , $stateChangeError included in the function parameters, but that caused error
$stateProvider.state('getLocation', {
url: '/getLocation',
templateUrl: 'getlocation.html',
controller: 'GetlocationCtrl',
});
})
.controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams", "$timeout",
function ($scope, $log, GoogleMapApi, $state, $stateParams, $timeout, $mdDialog) {
$log.currentLevel = $log.LEVELS.debug;
center = { latitude: 49.22, longitude: -122.66 }; //default center
console.log($stateParams);
$scope.map = {
center: center,
pan: false,
zoom: 16,
refresh: false,
events:
{ click: function newCenter(mapModel, eventName, originalEventArgs)
{
$scope.$apply(function(){
var e = originalEventArgs[0];
$scope.map.center = { latitude: e.latLng.lat(), longitude: e.latLng.lng() };
$timeout($scope.showConfirm($event), 500);
});
}
}
}
$scope.map.circle = {
id: 1,
center: center,
radius: 500, //(current time - date lost)*km/hour
stroke: {
color: '#08B21F',
weight: 2,
opacity: 1
},
fill: {
color: '#08B21F',
opacity: 0.5
},
geodesic: false, // optional: defaults to false
draggable: false, // optional: defaults to false
clickable: true, // optional: defaults to true
editable: false, // optional: defaults to false
visible: true, // optional: defaults to true
events: {
dblclick: function () {
$log.debug("circle dblclick");
},
radius_changed: function (gObject) {
var radius = gObject.getRadius();
$log.debug("circle radius radius_changed " + radius);
}
}
};
$scope.showConfirm = function (ev) {
// Appending dialog to document.body to cover sidenav in docs app
var confirm = $mdDialog.confirm()
.title('Would you like to delete your debt?')
.textContent('All of the banks have agreed to forgive you your debts.')
.ariaLabel('Lucky day')
.targetEvent(ev)
.ok('Please do it!')
.cancel('Sounds like a scam');
$mdDialog.show(confirm).then(function() {
$scope.status = 'You decided to get rid of your debt.';
}, function() {
$scope.status = 'You decided to keep your debt.';
});
};
} ]); //end of controller
//THIS LISTENER DOES NOT DO ANYTHING
// $scope.map.event.addListener(map, 'click', function(event) {
// alert(event.latLng); // in event.latLng you have the coordinates of click
//});
//function confirmLocation() {
// alert('Use this location as {{petName}}\'s last location?')
//}
})(window, angular);
Your controller does not have mdDialog injected, and there is a issue in the way you are injecting, change like below,
controller('GetlocationCtrl', ['$scope', "uiGmapLogger", "uiGmapGoogleMapApi", "$state", "$stateParams", "$timeout","$mdDialog",
function ($scope,uiGmapLogger, uiGmapGoogleMapApi, $state, $stateParams, $timeout, $mdDialog) {
I wanted to automatically center the map to the user's location once loaded so I used $scope.$apply() once geolocation is loaded as seen in my TestCtrl in controller.js here:
$scope.drawMap = function(position) {
$scope.$apply(function() {
$scope.myLocation.lng = position.coords.longitude;
$scope.myLocation.lat = position.coords.latitude;
$scope.map = {
center: {
latitude: $scope.myLocation.lat,
longitude: $scope.myLocation.lng
},
zoom: 14,
events: {
click: $scope.clickCallback
}
};
});
};
navigator.geolocation.getCurrentPosition($scope.drawMap);
$scope.test = function(){
alert("hola");
};
The $scope.clickCallback is used to push new markers to the map on click event.
// inside TestCtrl
var markers = [], counter = 1;
$scope.clickCallback = function(map, eventName, event){
var lat = event[0].latLng.lat();
var lng = event[0].latLng.lng();
markers.push(createNewMarker(counter, lat, lng));
$scope.$apply(function(){
$scope.newMarker = markers;
});
counter++;
};
As you can see, there's another $scope.$apply there to apply the new marker/s.
The createNewMarker() is where the markers (ui-gmap-markers) models is defined.
// still inside TestCtrl
var createNewMarker = function(i, lat, lng, idKey) {
if (idKey == null) {
idKey = "id";
}
var foo = "<h4>New Marker</h4><form><input type='text' placeholder='Event name' name='name'></input> <input type='button' value='submit'></input><input type='button' ng-click='test()' value='Delete marker'></input></form>";
var bar = $compile(foo)($scope);
var ret = {
latitude: lat,
longitude: lng,
show: true,
options: {
draggable: true,
animation: google.maps.Animation.DROP,
},
windows: {
title: "New Marker",
},
windowsOptions: {
content: foo,
}
};
ret[idKey] = i;
return ret;
};
Now the marker is showing fine when I click on the map including the window, but when I click on the Delete marker button, my $scope.test() function isn't firing up. I tried using $compile but it returns a bunch of error about $scope.
Here's my template:
<ion-content scroll="false">
<ui-gmap-google-map center='map.center' zoom='map.zoom' bounds="map.bounds" events="map.events">
<ui-gmap-markers models="newMarker" coords="'self'" icon="'icon'" options="'options'">
<ui-gmap-windows show="show" options="'windowsOptions'">
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</ion-content>
Anyone familiar with this scenario? I'm using Ionic Framework btw.
It does not have to be this complex.
As a creator of ngMap, I would recommend this,
http://ngmap.github.io/drawings.html#/marker-remove#marker-remove
To set the current location, just use current-location
<map center="current-location" zoom="12" on-click="addMarker()">
<marker ng-repeat="pos in positions" position="{{pos.lat}}, {{pos.lng}}"></marker>
</map>
http://plnkr.co/edit/e1SioHQ6NTSYCp0EbR0x?p=preview
I'm having an issue with angular google maps and the search box.
Even if the ng-view onLoad works as expected, after typing in the search box, the places_changed callbacks are not called from the correct controller but only from the first one (and the default) defined in $routeProvider.
You can find more details below:
Part of the template:
<div ng-controller="map">
<div>
<script type="text/ng-template" id="searchbox.tpl.html">
<input type="text" placeholder="Search Place..." class="google-maps-search">
</script>
<ui-gmap-google-map center='map.center' events="map.events" options="map.options" zoom='map.zoom'>
<ui-gmap-search-box template="map.searchbox.template" events="map.searchbox.events" position="BOTTOM_RIGHT"></ui-gmap-search-box>
<ui-gmap-marker coords="map.marker.coords" options="map.marker.options" events="map.marker.events" idkey="map.marker.id"></ui-gmap-marker>
<ui-gmap-markers models="mapMarkers" coords="'self'" icon="'icon'">
<ui-gmap-windows show="show">
<div ng-non-bindable>{{title}}</div>
</ui-gmap-windows>
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
<div><div ng-view="" onload="renderView()"></div></div>
Part of the parent controller:
app.controller('map', function ($scope, $log, $location) {
$scope.map = {
events: {
click: function(map, eventName, args) {}
},
marker: {
id: 0,
coords: {
latitude: $scope.lat,
longitude: $scope.lng
},
options: { draggable: true }
},
searchbox: {
template: 'searchbox.tpl.html',
events: {
places_changed: function (searchBox) {}
}
}
};
});
And the following in each of the children controllers (defined in $routeProvider):
$scope.map.searchbox.events.places_changed = function (searchBox) {
var place = searchBox.getPlaces();
if (!place || place == 'undefined' || place.length == 0) {
console.log('no place data :(');
return;
}
$scope.lat = place[0].geometry.location.lat();
$scope.lng = place[0].geometry.location.lng();
$scope.map.center = {
"latitude": $scope.lat,
"longitude": $scope.lng
};
$scope.renderView();
};
Do you have any ideas?
I'm trying to set bounds into Google Maps instance but with no success. I'm using AngularJS and angular-google-maps module. My last try was:
<div id="map_canvas">
<ui-gmap-google-map
center="map.center"
zoom="map.zoom"
bounds="map.bounds"
options="options">
<div ng-repeat="d in devicesMarkers track by d.id">
<ui-gmap-marker
idkey="d.id"
coords="d.center"
options="d.options">
</ui-gmap-marker>
<ui-gmap-circle
center="d.center"
stroke="d.circle.stroke"
fill="d.circle.fill"
radius="d.circle.radius"
visible="d.options.visible">
</ui-gmap-circle>
</div>
</ui-gmap-google-map>
</div>
In my app.js I wrote:
(...)
.controller('TaihMapController', ['$scope', '$log', 'uiGmapGoogleMapApi', function($scope, $log, GoogleMapApi) {
$scope.devicesMarkers = devices;
$scope.map = {
center: { latitude: devices[0].center.latitude, longitude: devices[0].center.longitude },
zoom: 12,
bounds: {}
// fit: true,
};
GoogleMapApi.then(function(maps) {
$log.debug(maps);
var myBounds = new maps.LatLngBounds();
for (var k = 0; k < devices.length; k++) {
var _tmp_position = new maps.LatLng(
devices[k].center.latitude,
devices[k].center.longitude);
myBounds.extend(_tmp_position);
}
$scope.map.bounds = myBounds;
$scope.googleVersion = maps.version;
// $scope.bounds = myBounds;
// $scope.zoom = maps.getZoom();
// maps.fitBounds(myBounds);
// $scope.bounds = maps.getBounds();
});
The function maps.fitBounds() doesn't exist. I try the $scope.map.bounds approach, but didn't respond the way I think.
If you're using angular-google-map's "markers" directive, just add the fit="true" attribute (ui-gmap-markers).
Example :
<ui-gmap-google-map center="map.center" zoom="map.zoom" options="map.options">
<ui-gmap-markers fit="true" models="markers" coords="'self'"></ui-gmap-markers>
</ui-gmap-google-map>
Source:
https://stackoverflow.com/a/29707965
According to docs, directives bounds is slightly different with google maps bounds. You should explicitly set northeast and southwest attributes with their own latitude and longitude.
Below should work:
$scope.map.bounds = {
northeast: {
latitude: myBounds.getNorthEast().lat(),
longitude: myBounds.getNorthEast().lng()
},
southwest: {
latitude: myBounds.getSouthWest().lat(),
longitude: myBounds.getSouthWest().lng()
}
};
I've implemented a very basic map using the angular-google-maps module. After the page has finished processing all scripts, I will always find a "TypeError: undefined is not a function" logged in the Chrome Developer Tools console, even though everything seems to work as expected.
It happens when $scope.control.getGMap().fitBounds($scope.bounds); is called within the uiGmapIsReady promise function.
angular.module('app', ['uiGmapgoogle-maps'])
.config(function (uiGmapGoogleMapApiProvider) {
uiGmapGoogleMapApiProvider.configure({
// key: 'your api key',
v: 3.17,
libraries: 'weather,geometry,visualization'
});
})
.controller('MainController', ['$scope', '$timeout', 'uiGmapGoogleMapApi', 'uiGmapIsReady', function ($scope, $timeout, uiGmapGoogleMapApi, uiGmapIsReady) {
$scope.markers = [
{ latitude: 33.970675, longitude: -118.454618},
{ latitude: 33.980675, longitude: -118.454618},
{ latitude: 33.974246, longitude: -118.455458}
]
uiGmapGoogleMapApi.then(function (maps) {
$scope.bounds = new maps.LatLngBounds();
angular.forEach($scope.markers, function (value, key) {
var myLatLng = new maps.LatLng($scope.markers[key].latitude, $scope.markers[key].longitude);
$scope.bounds.extend(myLatLng);
});
$scope.map = { center: { latitude: $scope.bounds.getCenter().lat(), longitude: $scope.bounds.getCenter().lng() }, zoom: 5 };
$scope.map.options = { MapTypeId: maps.MapTypeId.HYBRID };
});
$scope.control = {};
uiGmapIsReady.promise().then((function (maps) {
$scope.control.getGMap().fitBounds($scope.bounds);
}));
$scope.refreshMap = function () {
$scope.control.refresh({ latitude: $scope.bounds.getCenter().lat(), longitude: $scope.bounds.getCenter().lng() });
}
$scope.streetZoom = function () {
$scope.control.getGMap().setZoom(14);
}
}])
And here is the markup
<ui-gmap-google-map
center="map.center"
zoom="map.zoom"
options="map.options"
control="control">
<ui-gmap-marker idkey="$index" coords="item" ng-repeat="item in markers track by $index">
<ui-gmap-window options="windowOptions" closeclick="closeClick()">
<p class="google-window">{{item.latitude}}, {{item.longitude}}</p>
</ui-gmap-window>
</ui-gmap-marker>
</ui-gmap-google-map>
And here is the error message:
TypeError: undefined is not a function angular.js:11655
Any insight as to why this happens would greatly be appreciated! I feel like I've broken something and don't know why.