Angular Google Maps "Marker" directive not working - angularjs

Building a website that has 2 different google maps on the same page. The maps load fine. Im trying to add markers to the maps, and keep getting this error."MarkersParentModel: no valid models attribute "
My controller is :
angular.module('footStoreApp')
.controller('ContactpageCtrl', function ($scope, uiGmapGoogleMapApi) {
uiGmapGoogleMapApi.then(function(maps) {
});
$scope.map = { center: { latitude: 32.830593, longitude: -79.825432 }, zoom: 14 };
$scope.marker = {
id: 1,
coords: {
latitude: 32.830593,
longitude: -79.825432
},
};
$scope.map2 = { center: { latitude: 32.863488, longitude: -80.023833 }, zoom: 14 };
$scope.marker2 = {
id: 2,
coords: {
latitude: 32.863488,
longitude: -80.023833
}
}
});
The directives are :
<div>
<ui-gmap-google-map center='map.center' zoom='map.zoom'><ui-gmap-markers idkey='marker.id' coords='marker.coords'>
</ui-gmap-markers></ui-gmap-google-map>
</div>
<ui-gmap-google-map center='map2.center' zoom='map2.zoom'><ui-gmap-markers idkey='marker2.id' coords='marker2.coords'>
</ui-gmap-markers></ui-gmap-google-map>

You have used ui-gmap-markers directive instead of ui-gmap-marker.
See the documentation (http://angular-ui.github.io/angular-google-maps/#!/api). there are two directives (marker and markers).
Corrected Code:
var myApp = angular.module('myapp', ['uiGmapgoogle-maps']);
myApp.controller('MyCtrl1', function ($scope, uiGmapGoogleMapApi) {
uiGmapGoogleMapApi.then(function (maps) {
$scope.map = {
center: {
latitude: 32.830593,
longitude: -79.825432
},
zoom: 14
};
$scope.marker = {
id: 1,
coords: {
latitude: 32.830593,
longitude: -79.825432
}
};
$scope.map2 = {
center: {
latitude: 32.863488,
longitude: -80.023833
},
zoom: 14
};
$scope.marker2 = {
id: 2,
coords: {
latitude: 32.863488,
longitude: -80.023833
}
}
});
})
.angular-google-map-container {
height: 400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.8.0/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-google-maps/2.1.1/angular-google-maps.min.js"></script>
<div ng-app="myapp">
<div ng-controller="MyCtrl1">
<ui-gmap-google-map center='map.center' zoom='map.zoom'>
<ui-gmap-marker idkey='marker.id' coords='marker.coords'></ui-gmap-marker>
</ui-gmap-google-map>
<hr/>
<ui-gmap-google-map center='map2.center' zoom='map2.zoom'>
<ui-gmap-marker idkey='marker2.id' coords='marker2.coords'></ui-gmap-marker>
</ui-gmap-google-map>
</div>
</div>

Related

Scope is not filling when I try to set it after a ajax request

I'm trying to get data from an API and using this data to make up Google Maps.
But unfortunately it's not working when I set data in side of .then().
This is my controller
var alertController = function alertController($scope, alertData) {
// Local variable private variable
var _data;
// Retrieving data from API
alertData.getData()
.then(function(data){
_data = data;
// Setting scope variables
$scope.options = {
scrollwheel: false
};
$scope.markers = alertData.locations;
$scope.map = { center: { latitude: _data.latitude, longitude: _data.longitude }, zoom: 16 };
})
.catch(function(data, status, headers, config){
$log.warn(data, status, headers, config);
});
// _data is undefined here, how can i make it "defined"
}
alertApp.controller('alertController', alertController);
My service
function alertData($http){
var alertData = {};
alertData.getData = function() {
var settings = {
"url": "url",
"method": "POST",
"headers": {
"Accept": "application/vnd.api+json",
"Auth-Token": "token",
"Content-type": "application/vnd.api+json",
},
"data": "{ data }"
}
return $http(settings);
};
alertData.locations = [
{id: 1, latitude: 52.012812, longitude: 4.365468, title: "1"},
{id: 2, latitude: 52.012832, longitude: 4.365475, title: "2"},
{id: 3, latitude: 52.012843, longitude: 4.365448, title: "3"},
{id: 4, latitude: 52.012843, longitude: 4.365238, title: "4"},
{id: 5, latitude: 52.012812, longitude: 4.361748, title: "5"},
{id: 6, latitude: 52.012865, longitude: 4.3653458, title: "6"},
{id: 7, latitude: 52.012876, longitude: 4.365768, title: "7"},
{id: 8, latitude: 52.012865, longitude: 4.365348, title: "8"},
{id: 9, latitude: 52.012845, longitude: 4.365758, title: "9"},
{id: 10, latitude: 52.012834, longitude: 4.3654475, title: "10"},
{id: 11, latitude: 52.012816, longitude: 4.3654345, title: "11"},
{id: 12, latitude: 52.012826, longitude: 4.365472, title: "12"},
{id: 13, latitude: 52.012815, longitude: 4.365457, title: "13"},
{id: 14, latitude: 52.012838, longitude: 4.365427, title: "14"},
];
return alertData;
}
alertApp.factory('alertData', alertData);
The HTML
<div id="container" class="container" ng-controller="alertController">
<ui-gmap-google-map center='map.center' options="options" zoom='map.zoom'>
<ui-gmap-markers models="markers" coords="'self'" icon="'icon'">
</ui-gmap-markers>
</ui-gmap-google-map>
</div>
Any ideas on how I can achieve waiting till I get data and than fill the scope and let Google Maps init?
UPDATE
When I console.log(_data) after getData(), it says undefined and come before the console.log(_data) inside of the .then() which gives the right json
Based on your comments I suggest you to put a condition for showing your google map only when all required data is ready, so this way you can wait until all data is ready for "building" the component. Something like this:
<div id="container" class="container" ng-controller="alertController" data-ng-if="dataReady">
<!-- google maps component here-->
</div>
And in your controller:
// Retrieving data from API
alertData.getData()
.then(function(data){
//...
$scope.dataReady = true;
})
.catch(function(data, status, headers, config){
//...
});
Important: Use ng-if instead of ng-show/ng-hide since the first one creates/removes elements from the DOM and the second one just applies css classes for displaying or not the component. With the ng-if the google maps component is created when all required data is ready.

How to get on-click coordinates on angular google maps?

I'm kind of a newb when it comes to AngularJS and Google's API for maps and I've been trying to get coordinates on click. I'm using this API.
I am getting an error: Uncaught TypeError: Cannot read property 'lat' of undefined
on "console.log(lat);" row
This is my angular controller:
app.controller("agencyController",['$scope', '$log','uiGmapGoogleMapApi', function($scope,$interval, GoogleMapApi){
markers = [],
angular.extend($scope, {
markeri : markers,
map : {
center: bgdcentar,
zoom:13,
options: {
mapTypeId : google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
streetViewControl: false,
styles: [{"featureType":"administrative","elementType":"labels.text.fill","stylers":[{"color":"#444444"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"simplified"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#46bcec"},{"visibility":"on"}]}],
disableDoubleClickZoom: true,
scaleControl: true,
scrollwheel: true,
panControl: true,
streetViewControl: false,
draggable: true,
overviewMapControl: true,
},
events:{
rightclick: function(event){
var lat = event.latLng.lat();
var lng = event.latLng.lng();
console.log(lat);
console.log(lng);
console.log('Stan dodat!');
markers.push();
},
},
},
searchbox : {
template: 'searchbox.tpl.html',
events:{
places_changed: function(searchBox){
},
parentdiv: 'map_canvas'
}
},
});
}]);
And this is a part of my html, the code is included in the controller so don't worry about that:
<div id="map_canvas">
<ui-gmap-google-map center='map.center' zoom='map.zoom' options='map.options' events='map.events' >
<ui-gmap-search-box template="searchbox.template" events="searchbox.events"></ui-gmap-search-box> <!-- search-->
<ui-gmap-markers models="markeri" coords="'self'" icon="'icon'"></ui-gmap-markers> <!-- markeri -->
</ui-gmap-google-map>
</div>
You need to replace:
rightclick: function(event){
//...
}
with:
rightclick: function (map, eventName, events) {
var event = events[0];
//...
}
where
map refers to map object,
eventName - the name of event
events - the list of event listeners
Example
angular.module('appMaps', ['uiGmapgoogle-maps'])
.config(function(uiGmapGoogleMapApiProvider) {
uiGmapGoogleMapApiProvider.configure({
//key: ''
});
})
.controller("mainCtrl", ['$scope', '$log', 'uiGmapGoogleMapApi',
function($scope, $interval, GoogleMapApi) {
angular.extend($scope, {
markers: [],
markerNo: 1,
map: {
center: {
latitude: 42.3349940452867,
longitude: -71.0353168884369
},
zoom: 13,
options: {
},
events: {
rightclick: function(map, eventName, events) {
var event = events[0];
var lat = event.latLng.lat();
var lng = event.latLng.lng();
$scope.$apply(function() {
$scope.markers.push({
latitude: lat,
longitude: lng,
id: $scope.markerNo
});
$scope.markerNo++;
});
},
},
}
});
}
]);
.angular-google-map-container {
position: absolute;
width: 100%;
height: 240px;
}
<script src="https://code.angularjs.org/1.3.14/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="http://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script>
<div id="map_canvas" ng-app="appMaps" ng-controller="mainCtrl">
<ui-gmap-google-map center='map.center' zoom='map.zoom' options='map.options' events='map.events'>
<ui-gmap-markers models="markers" coords="'self'" icon="'icon'"></ui-gmap-markers>
</ui-gmap-google-map>
</div>

on-click marker in ngMap with id?

I am using ngMap to display a map with markers on it. I want to redirect the user to a URL, when he clicks a marker. To build this URL, i need a unique id, from the repeat.
I have this;
<marker ng-repeat="position in ctrl.positions" position="{{position.x}}, {{position.y}}" on-click="ctrl.goto(ctrl.id)"></marker>
In my controller i have
vm.clickRedirect = function(pId) {
console.log(pId);
}
I just return the object, and the actual id (ctrl.id). How do i achive this?
To pass object identifier as a parameter via on-click event replace clickRedirect function to:
vm.clickRedirect = function(event,pId) {
console.log(pId);
}
Working example
angular.module('mapApp', ['ngMap'])
.controller('mapCtrl', function ($scope, NgMap) {
NgMap.getMap().then(function (map) {
$scope.map = map;
});
$scope.cities = [
{ id: 1, name: 'Oslo', pos: [59.923043, 10.752839] },
{ id: 2, name: 'Stockholm', pos: [59.339025, 18.065818] },
{ id: 3, name: 'Copenhagen', pos: [55.675507, 12.574227] },
{ id: 4, name: 'Berlin', pos: [52.521248, 13.399038] },
{ id: 5, name: 'Paris', pos: [48.856127, 2.346525] }
];
$scope.showInfo = function (event,id) {
$scope.selectedCity = $scope.cities.filter(function(c){
return c.id === id;
})[0];
};
});
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://maps.googleapis.com/maps/api/js?key="></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<div ng-app="mapApp" ng-controller="mapCtrl">
<div>Selected city: {{selectedCity}}</div>
<ng-map zoom="4" center="59.339025, 18.065818">
<marker ng-repeat="c in cities" position="{{c.pos}}" title="{{c.name}}" id="{{c.id}}" on-click="showInfo(c.id)">
</marker>
</ng-map>
</div>
on-click is not an angular expression
you need to use angular expression to evaluate ctrl.id
like this : {{ctrl.id}}
Or did you mean to use ng-click?

how to get a particular location on google maps with markers from a angular dropdown list

I am trying to do some location search on google maps,its like i am having a angular multi-select drop-down where i am having several locations, if i select a single location or more ,i have to show them on maps using markers,and how to get our current location any suggestions on how to do it please.
Dropdown code
<div class="m-r"
ng-dropdown-multiselect=""
options="locations"
selected-model="search.locations"
extra-settings="multiSelectSettingsFunction"
translation-texts ="locationsTexts"
settings="selectSettings">
</div>
Google maps code
<ui-gmap-google-map center="map.center" refresh="true" zoom="map.zoom" draggable="true" data-tap-disabled="true">
<ui-gmap-window show="map.window.show" coords="map.window.model" options="map.window.options" closeClick="map.window.closeClick()">
<div style="color: black" background-color="#337ab7">
{{map.window.title}}
{{map.window.venue}}
</div>
</ui-gmap-window>
<ui-gmap-markers idkey="marker.id" models="map.markers" coords="'self'" doCluster="false" fit="'true'" icon="'icon'" events="map.markersEvents " options="'options'"></ui-gmap-markers>
</ui-gmap-google-map>
controller.js
app.controller("MainController", [ '$anchorScroll', '$scope', '$http', '$modal', '$log', '$timeout', '$location', '$rootScope', '$window','$mdSidenav' , function ($anchorScroll, $scope, $http, $modal, $log, $timeout, $location, $rootScope, $window,$mdSidenav) {
$scope.searchBack = window.sessionStorage.searchBack;
$scope.search = {
pax: '',
data: '',
locations : [],
distance : []
}
$scope.$watch('search.locations', function(newVal, oldVal){
//console.log(newVal);
//$scope.setSearch();
}, true);
$scope.locationsTexts = {
buttonDefaultText: 'Locations',
dynamicButtonTextSuffix: 'Locations',
}
$scope.multiSelectSettings = {
displayProp: 'locations',
idProp: 'locations',
scrollableHeight: '256px',
scrollable: true,
enableSearch: true,
buttonDefaultText: 'asd',
dynamicButtonTextSuffix: 'Locations',
//showCheckAll: false,
};
$scope.locations = [
{id: 1, label: "kothapet"},
{id: 2, label: "Dsnr"},
{id: 3, label: "Malakpet"},
{id: 4, label: "Chadarghat"},
{id: 5, label: "Koti"},
{id: 6, label: "abids"}
];
Maps Controller
app.controller('MapController2', function($scope, $rootScope, $http) {
var data = {};
data.map = {
zoom: 16,
center: {
latitude: 17.399,
longitude: 78.52
},
markers: [
{
id: 1,
latitude: 17.3762,
longitude: 78.5461,
title: 'Location:Nagole',
venue:'Venue: Ng builders'
},
{
id: 2,
latitude: 17.3710,
longitude: 78.5410,
title: 'Location:Kothapet',
venue:'Venue: A Builders'
},
{
id: 3,
latitude: 17.3688,
longitude: 78.5247,
title: 'Location:Dilsukhnagar',
venue:'Venue: B Builders'
},
{
id: 4,
latitude: 17.3667,
longitude: 78.500,
title: 'Location:Malakpet',
venue:'Venue: C Builders'
}],
markersEvents: {
click: function(marker, eventName, model, arguments) {
console.log('Marker was clicked (' + marker + ', ' + eventName);//+', '+mydump(model, 0)+', '+mydump(arguments)+')');
$scope.map.window.model = model;
$scope.map.window.model = model;
$scope.map.window.title = model.title;
$scope.map.window.venue = model.venue;
$scope.map.window.show = true;
}
},
window: {
marker: {},
show: false,
closeClick: function() {
this.show = false;
},
options: {}, // define when map is ready
title: ''
}
};
//$scope.window = false;
$scope.onMarkerClicked = function (m) {
//this.windowOptions = !this.windowOptions;
console.log('Marker was clicked');
console.log(m);
};
$scope.closeClick = function () {
this.window = false;
};
$scope.map = data.map;
});
1) To resolve location by address name utilize Google Maps Geocoding API, for example:
var resolveAddress = function(address) {
var deffered = $q.defer();
$http({
url: 'http://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&sensor=false',
method: 'GET'
}).
success(function(data) {
deffered.resolve(data);
}).
error(function(error) {
deffered.reject();
});
return deffered.promise;
};
2) For angularjs-dropdown-multiselect component you could utilize events to add events what the directive fires, for example onItemSelect which triggers once the item is selected:
<div class="m-r"
ng-dropdown-multiselect=""
options="locations"
selected-model="search.locations"
translation-texts="locationsTexts"
settings="selectSettings"
events="{ onItemSelect: showItemOnMap }">
</div>
$scope.showItemOnMap = function(item) {
//...
};
The following demo demonstrates how to display markers on map from items selected in angularjs-dropdown-multiselect control
Demo

In angular-google-maps, what's the right way to bind to click events on a polygon

I'm trying to bind a function to a click event on a polygon in Google maps using angular-google-maps. Here's how I define the polygon:
<ui-gmap-google-map center='map.center' zoom='map.zoom'>
<ui-gmap-polygon static="true" ng-repeat="p in polygons track by p.id"
path="p.path" stroke="p.stroke" visible="p.visible"
fill="p.fill" clickable="true" events="p.events">
</ui-gmap-polygon>
</ui-gmap-google-map>
and here's the code in the controller:
$scope.map = { center: { latitude: 3, longitude: 49 }, zoom: 7 };
// preset polygons
$scope.polygons = [
{
id: 1,
path: [
{ latitude: 12, longitude: 50 },
{ latitude: 27, longitude: 54 },
{ latitude: 24, longitude: 45 },
],
stroke: { color: '#ff0000', weight: 2 },
visible: true,
fill: { color: '#ff0000', opacity: 0.3 },
events: { click: function() { console.log("clicked!"); }},
}
];
The polygon appears fine and everything, the only problem is that I can't bind the click event. Can anyone help me figure out the right way to do that?
Thanks a lot!
I eventually found out that my problem was actually related to mobile (more specifically, Ionic). There's a difference between tap and click.
Found this solution: https://github.com/angular-ui/angular-google-maps/issues/428
Works great.

Resources