I'm making a little app for training with AngularJS, and I have a problem.
I'm receiving JSON data through an API, and then I display it in a map using leaflet directives for Angular.
The problem is one of the thing I try to display give me an error.
This is my controller :
toulouseVeloControllers.controller('toulouseVeloListCtrl', ['$scope', '$http',
function($scope, $http) {
angular.extend($scope, {
osloCenter: {},
markers: {},
defaults: {
scrollWheelZoom: false
}
});
$http.get('https://api.jcdecaux.com/vls/v1/stations?contract=toulouse&apiKey=*************************************').success(function(data) {
$scope.bornes = data;
$scope.markers=[];
$scope.osloCenter=[];
for (var i = 0; i < data.length; i++) {
$scope.markers[i] = {
lat: data[i].position.lat,
lng: data[i].position.lng,
message: data[i].available_bikes,
focus: false,
draggable: false
};
}
$scope.osloCenter = {
lat: data[10].position.lat,
lng: data[10].position.lng,
zoom: 15
};
});
}]);
And this is my HTML :
<div ng-controller="toulouseVeloListCtrl">
<leaflet markers="markers" center="osloCenter" style="width: 100%; height: 500px;"></leaflet>
</div>
In $scope.markers[i], when I try to show data[i].available_bikes, it give me an error, but if I try to show other like data[i].name or data[i].address, there is no problem.
Anyone can tell me what is wrong here ?
Thank you a lot !
The contents of the popup needs to be a string.
for (var i = 0; i < data.length; i++) {
$scope.markers[i] = {
lat: data[i].position.lat,
lng: data[i].position.lng,
message: "Available Bikes: " + data[i].available_bikes,
focus: false,
draggable: false
};
}
https://jsfiddle.net/tombatossals/4PhzC/
Related
hi create real estate app i have problem in google map if i call location from Json I get error Like this
my html code
name: "Property",
data() {
return {
ref: this.$route.params.ref,
propertydata: {},
center: { lat: 45.508, lng: -73.587 },
markers: [],
places: [],
currentPlace: null
};
},
created() {
this.$http
.get("http://localhost:3000/Listing/" + this.ref)
.then(function(data) {
console.log(data);
this.propertydata = data.body;
this.center=data.body.latitude;
this.center=data.body.longitude;
th
});
<gmap-map :center="{lat: {{propertydata.latitude}} , lng: {{propertydata.longitude}} } " :zoom="14" style="width:500px; height:500px;"></gmap-map>
- invalid expression: Unexpected token { in
{lat: {{propertydata.latitude}} , lng: {{propertydata.longitude}} }
Raw expression: :center="{lat: {{propertydata.latitude}} , lng: {{propertydata.longitude}} } "
my location details from json how to fix this i have no idea
The right way to declare the component is:
<gmap-map :center="{lat: propertydata.latitude, lng: propertydata.longitude}" :zoom="14" style="width:500px; height:500px;"></gmap-map>
You should use {{...}} syntax only inside tags, not in tag attributes.
I'm using ngMap on a project where I have different maps on different views. I have one initial page where I show a map and draw a polygon and some markers. My controller is like this:
$scope.showInitialMap = function( map ) {
/*Resize image to show on map*/
var iconGood = {
url: 'modules/cars/img/ambulance_ok.png',
scaledSize: new google.maps.Size( 40, 40 ),
origin: new google.maps.Point( 0, 0 ),
anchor: new google.maps.Point( 0, 0 )
};
/*Get all cars*/
$scope.tracks = Tracks.getTaxisRealTime( function() {
angular.forEach( $scope.tracks, function( c ) {
var infowindow = new google.maps.InfoWindow( {
content: contentString
} );
/*Set marker position fo each car*/
var marker = new google.maps.Marker( {
position: {
lat: c.Latitude,
lng: c.Longitude
},
icon: iconGood,
map: map
} );
} );
/*draw map*/
setArea( map );
} );
};
and I just add it to the view like this:
<section data-ng-controller="MapsCtrl" ng-init="InitTaxiHistory()">
<ng-map center="[19.54, -96.91]" zoom="13" style="height: 600px;" min-zoom="12">
</ng-map>
</section>
The problem is that when I go to a different view where I also show a map, it keeps the same state where I left the previous map.
How do I reset the map? Or how create 2 different instances for a map?
Creating new instance of Google Map will make question complex and not recommended at all.
see relevant issues:
What is the Proper Way to Destroy a Map Instance?
How to destroy or reset map?
Solution
And for your situation, you can deal with each ng-map with making googlemap show different things according to your current controller.
<ng-map>
<marker ng-repeat="marker in tracks" position="{{marker. Latitude}}, {{marker. Longitude}}"></marker>
<ng-map>
the markers will be removed automitically if there isn't data in $scope.tracks and if $scope.tracks is undefined.
Plunker demo.
Since NgMap extends google.maps.Map object to store all the objects (markers, shapes) you could clear the map by calling setMap() method:
$scope.clearMap = function () {
//clear markers
for (var k in $scope.map.markers) {
$scope.map.markers[k].setMap(null);
}
//clear shapes
for (var k in $scope.map.shapes) {
$scope.map.shapes[k].setMap(null);
};
};
Example
var app = angular.module('appMaps', ['ngMap']);
app.controller('mapCtrl', function ($scope, NgMap) {
$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] }
];
NgMap.getMap().then(function (map) {
$scope.map = map;
});
$scope.clearMap = function () {
//clear markers
for (var k in $scope.map.markers) {
$scope.map.markers[k].setMap(null);
}
//clear shapes
for (var k in $scope.map.shapes) {
$scope.map.shapes[k].setMap(null);
};
};
$scope.showMap = function () {
//clear markers
for (var k in $scope.map.markers) {
$scope.map.markers[k].setMap($scope.map);
}
//clear shapes
for (var k in $scope.map.shapes) {
$scope.map.shapes[k].setMap($scope.map);
};
};
});
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://rawgit.com/allenhwkim/angularjs-google-maps/master/build/scripts/ng-map.js"></script>
<div ng-app="appMaps" ng-controller="mapCtrl">
<button ng-click="clearMap()">Clear All</button>
<button ng-click="showMap()">Show All</button>
<map center="[59.339025, 18.065818]" zoom="4">
<marker id='ID{{city.id}}' ng-repeat="city in cities" position="{{city.pos}}" >
</marker>
<shape name="rectangle" bounds="[ [57.190, 16.149], [59.899, 20.443] ]"></shape>
</map>
</div>
I am using Angular-google-maps, HTML code follows
<ui-gmap-google-map center='mapData.map.center' zoom='mapData.map.zoom'
events="mapEvents">
<ui-gmap-markers models="mapData.map.markers" coords="'self'">
</ui-gmap-markers>
</ui-gmap-google-map>
in JS calling
angular.extend(this, $controller('MapsMixinController',
{$scope:$scope, map:mapData.data[0].map}));
MapsMixinController as follows. Calling this controller from js code. Markers are showing & on click able to mark.
MapsMixinController.js
/**
* Controller providing common behaviour for the other map controllers
*/
angular
.module('app')
.controller('MapsMixinController', ['$scope', 'GeolocationService', 'uiGmapGoogleMapApi', 'map',
function($scope, GeolocationService, GoogleMapApi, map) {
var _this = this;
$scope.mapEvents = {
click: function(mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
if (e.latLng) {
$scope.mapData.map.markers.push({
id: new Date().getTime(),
latitude: e.latLng.lat(),
longitude: e.latLng.lng()
});
// This event is outside angular boundary, hence we need to call $apply here
$scope.$apply();
}
}
};
// Returns a default map based on the position sent as parameter
this.getDefaultMap = function(position) {
return {
markers: [],
center: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
zoom: 14
};
};
// Initialize the google maps api and configure the map
GoogleMapApi.then(function() {
GeolocationService().then(function(position) {
$scope.mapData.map = map || _this.getDefaultMap(position);
}, function() {
$scope.error = "Unable to set map data"; // TODO use translate
});
});
}
]);
How can I show title on mouse hover on markers? And on click how to show description on markers?
You can add title property alone with latitude and longtitude property while creating marker data.
/**
* Controller providing common behaviour for the other map controllers
*/
angular
.module('app')
.controller('MapsMixinController', ['$scope', 'GeolocationService', 'uiGmapGoogleMapApi', 'map',
function($scope, GeolocationService, GoogleMapApi, map) {
var _this = this;
$scope.mapEvents = {
click: function(mapModel, eventName, originalEventArgs) {
var e = originalEventArgs[0];
if (e.latLng) {
$scope.mapData.map.markers.push({
id: new Date().getTime(),
latitude: e.latLng.lat(),
longitude: e.latLng.lng(),
title: "Mouse over text"
});
// This event is outside angular boundary, hence we need to call $apply here
$scope.$apply();
}
}
};
// Returns a default map based on the position sent as parameter
this.getDefaultMap = function(position) {
return {
markers: [],
center: {
latitude: position.coords.latitude,
longitude: position.coords.longitude
},
zoom: 14
};
};
// Initialize the google maps api and configure the map
GoogleMapApi.then(function() {
GeolocationService().then(function(position) {
$scope.mapData.map = map || _this.getDefaultMap(position);
}, function() {
$scope.error = "Unable to set map data"; // TODO use translate
});
});
}
]);
My app needs to get a path ( list of latitude and longitudes )in order to display it on a map.
I created a basic controller that does all the api calls.
function mainController($scope, $http){
$http.get('/api/lastrun')
.success(function(data){
$scope.lastrun = data;
})
.error(function(data){
console.log('Error: ' + data);
});
}
lastrun has a path array that lets you access the each position.
I created a mapController using angular-leaf-directive
function mapController($scope, positionService){
angular.extend($scope, {
run: {
lat: 0.0,
lng: 0.0,
zoom: 4
},
path: {
p1: {
color: 'red',
weight: 2,
latlngs: [
{ lat: 51.50, lng: -0.082 }, //here is an example of lat and lng in this controller
{ lat: 48.83, lng: 2.37 },
{ lat: 0, lng: 7.723812 }
]
}
}
});
}
What I want to do seems pretty easy. I just want to put the array of positions I get while calling /api/lastrun into my mapController in latlngs.
I'm not completely familiar with Services in AngularJS, but I tried to built mine (positionService). However it didn't work.
Does anyone here know how I can proceed in order to create with my service an array containing a list of {lat : , lng: } and call it into my mapController ?
I would have done :
$scope.lastrun = [];
$http.get('/api/lastrun')
.success(function(data){
angular.forEach(data, function (value) {
$scope.lastrun.push({lat : value.lat, lng : value.lng});
});
}
})
and then :
path: {
p1: {
color: 'red',
weight: 2,
latlngs: $scope.lastrun
}
Hope this helps
I have finally found a solution. I use Adrien's solution in my service, not in my controller and then return the lastrunpos array to my mapController. Here's my code :
var selftracking = angular.module('selftracking',["leaflet-directive"])
selftracking.service('positionService', function($http){
var lastrunpos = [];
$http.get('/api/lastrun')
.success(function(data){
angular.forEach(data.path, function (value) {
lastrunpos.push({lat : value.latitude, lng : value.longitude});
});
});
return {
getPos : function() {
return lastrunpos;
}
}
});
function mainController($scope, $http){
//Get all the last activities in the front page
$http.get('/api/lastactivity')
.success(function(data){
$scope.lastactivity = data;
})
.error(function(data){
console.log('Error: '+ data);
});
$http.get('/api/lastrun')
.success(function(data){
$scope.lastrun = data;
})
.error(function(data){
console.log('Error: ' + data);
});
}
function mapController($scope, positionService){
angular.extend($scope, {
run: {
lat: 51.505,
lng: -0.09,
zoom: 4
},
path: {
p1: {
color: 'red',
weight: 8,
latlngs: positionService.getPos()
}
}
});
}
I'm attempting to use this Google Maps for AngularJS directive inside another function. The code works when I move $scope.map outside the function call and set the lat/lon statically. However, what I want to do is set the lat/lon dynamically within my function call.
Code below.
html:
<google-map center="map.center" zoom="map.zoom"></google-map>
Angular controller:
angular.module('StadiumCtrl', []).controller('StadiumController', function($scope, $rootScope, $routeParams, $sce, Stadia, Instagram, Weather) {
// pull stadium details from API based on routeParams
$scope.id = $routeParams.id;
Stadia.get($scope.id).success(function(response) {
$rootScope.logo = response.logo;
$scope.homeColors = {
"border": "2px solid " + response.sec_hex,
"box-shadow": "3px 3px 7px " + response.prim_hex,
"margin": "6px",
"padding": "0"
}
$scope.map = {
center: {
latitude: response.loc[1],
longitude: response.loc[0]
},
zoom: 8
};
// pass loc_id into Instagram API call
Instagram.get(response.loc_id).success(function(response) {
instagramSuccess(response.loc_id, response);
});
// pass city and state into Wunderground API call
Weather.get(response.city, response.state).success(function(response) {
$rootScope.temp = Math.round(response.current_observation.temp_f);
});
// Instagram API callback
var instagramSuccess = function(scope,res) {
if (res.meta.code !== 200) {
scope.error = res.meta.error_type + ' | ' + res.meta.error_message;
return;
}
if (res.data.length > 0) {
$scope.items = res.data;
} else {
scope.error = "This location has returned no results";
}
};
});
It looks like the google-maps directive needs an initial value when the directive gets linked. Once there is a default value it will respond to changes in that scope value.
You can see this in action with the following code:
$scope.map = {center: {latitude:0,longitude:0}, zoom: 0};
$timeout(function() {
$scope.map = {center: {latitude: 51.219053, longitude: 4.404418 }, zoom: 14 };
}, 1000);
which is demonstrated at http://plnkr.co/edit/szhdpx2AFeDevnUQQVFe?p=preview. If you comment out the $scope.map assignment outside the $timeout the map will no longer show up, but if you put line 3 back it in will update the map when the $timeout executes.
In your case, you should simply be able to add
$scope.map = {
center: {
latitude: 0,
longitude: 0
},
zoom: 0
};
just before you run Stadia.get($scope.id).success(function(response) {.