How to access variable in angular scope? - angularjs

When I insert console.log($scope) into my code, I get the following result:
$get.k.$new.a.$$childScopeClass.$$childScopeClass {$$childTail: null, $$childHead: null, $$nextSibling: null, $$watchers: Array[4], $$listeners: Object…}
$$childHead: null
$$childScopeClass: null
$$childTail: null
$$listenerCount: Object
$$listeners: Object
$$nextSibling: null
$$prevSibling: $get.k.$new.a.$$childScopeClass.$$childScopeClass
$$watchers: Array[4]
$id: "005"
$parent: Object
Bad: false
Good: true
Search: function () {
address: "63146"
focus: "63146"
this: $get.k.$new.a.$$childScopeClass.$$childScopeClass
__proto__: Object
The variable I am interested in is Good: true. However, when I call console.log($scope.Good) on the next line, it returns false.
How do I call the above "Good" variable that returns true in the console?
edit:
Controller
app.controller('locationController', function ($scope) {
$scope.Good = false;
$scope.Bad = false;
var mapOptions = {
center: { lat: 38.68, lng: -90.46 },
zoom: 8
};
var image = {
url: 'app/assets/img/marker.png'
}
var map = new google.maps.Map(document.getElementById('map'),
mapOptions);
$scope.Search = function () {
$scope.Good = false;
$scope.Bad = false;
var address = $scope.address;
var radius = parseInt(50, 10) * 1000;
var marker_start = new google.maps.Marker({
position: { lat: 38.688757, lng: -90.464391 },
map: map,
icon: image,
title: ""
});
var fill = '#fff';
var populationOptions = {
strokeColor: '#66FF99',
strokeOpacity: 0.2,
strokeWeight: 2,
fillColor: fill,
fillOpacity: 0.35,
map: map,
center: new google.maps.LatLng(38.68, -90.46),
radius: 80000
};
var lat = '';
var lng = '';
var geocoder = new google.maps.Geocoder();
var marker_user = null;
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
lat = results[0].geometry.location.lat();
lng = results[0].geometry.location.lng();
marker_user = new google.maps.Marker({
position: { lat: lat, lng: lng },
map: map,
animation: google.maps.Animation.DROP,
title: "Your Location"
});
if (google.maps.geometry.spherical.computeDistanceBetween(marker_user.getPosition(), marker_start.getPosition()) < 80000)
$scope.$apply(function () { $scope.Good = true; });
else
$scope.$apply(function () { $scope.Bad = true; });
}
});
console.log($scope);
console.log($scope.Good);
console.log($scope.Bad);
var cityCircle = new google.maps.Circle(populationOptions);
};
});

Good becomes true only after the callback function passed to geocoder.geocode() has been called. But you're printing it before it has been called, right after having asked the geocoder to geocode.
ask the geocoder to geocode. This sends an HTTP request to Google
print Good: it's still false
when the response from Google comes in, the callback is executed and Good becomes true

Related

How to merge two different object from JSON data

Hi I need some help with this code snippet. The output that I get is multiple different objects of JSON data. But I want to extract the destination data then merge them as an array. But all the data I get is only one data merge as an array, one by one.
Here is the output:
$scope.findHospital = function(){
$ionicLoading.show({
template: '<ion-spinner icon="bubbles"></ion-spinner><br/>Acquiring location!'
});
var posOptions = {
enableHighAccuracy: true,
timeout: 20000,
maximumAge: 0
};
$cordovaGeolocation.getCurrentPosition(posOptions).then(function (position) {
var lat = position.coords.latitude;
var long = position.coords.longitude;
var infowindow;
var myLatlng = new google.maps.LatLng(lat, long);
var mapOptions = {
center: myLatlng,
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map"), mapOptions);
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.nearbySearch({
location: myLatlng,
radius: 5000,
type: ['police']
}, callback);
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(lat, long);
geocoder.geocode({'latLng': latlng}, function(results, status) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
var request = { reference: place.reference };
service.getDetails(request, function(details, status) {
console.log(details);
var url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+results[0].formatted_address+"&destinations="+details.formatted_address+"&key=AIzaSyDDxMGpu5SP5XwZGrKw5BQWl_r2dgLgpPY";
var distances = [];
$http.get(url).then(function(response){
var str = response.data.rows[0].elements[0].distance.text;
distances = distances.concat(str);
console.log(distances);
});
}
});
}
}
}
CODE UPDATED!
I strongly suspect, distances array is initializing everytime when createMarker method is called. So, put your distances in global scope. i.e. just above your resolving getCurrentPosition promise.
var distances = [];
$cordovaGeolocation.getCurrentPosition(posOptions).then(function (position) {
// your code
and remove distances intialization from inner code.
This is what you need!! A array outside of your function createMarker. When you call $http.get, you should concatenate the response with your distances array.
var distances = []; // HERE
function createMarker(place) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(lat, long);
geocoder.geocode({'latLng': latlng}, function(results, status) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
var request = { reference: place.reference };
service.getDetails(request, function(details, status) {
var url = "https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+results[0].formatted_address+"&destinations="+details.formatted_address+"&key=AIzaSyDDxMGpu5SP5XwZGrKw5BQWl_r2dgLgpPY";
$http.get(url).then(function(response){
var str = response.data.rows[0].elements[0].distance.text;
distances = distances.concat(str); // HERE
});
}
});
}

Incorrect marker location

I am Using the $http Service in Ionic to dynamically load Google Map Markers, and I use this method:
google.maps.Geocode
To give a lat and lang, but this code is throwing some error.
facebookExample.controller('carteController', function ($scope, $ionicLoading, $location, $cordovaGeolocation, $compile, $http) {
$scope.back = function () {
$location.path("/accueil");
}
$scope.init = function () {
$http.get('http://#ip:8080/elodieService/categories/', {
params: {
fields: "nomcategorie,typecategorie",
format: "json"
}
}).then(function (result) {
console.log("SUCCESS!" + result.data);
console.log(JSON.stringify(result));
$scope.categorieData = result.data;
});
var options = {timeout: 10000, enableHighAccuracy: true};
$cordovaGeolocation.getCurrentPosition(options).then(function (position) {
var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var mapOptions = {
center: latLng,
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);
google.maps.event.addListenerOnce($scope.map, 'idle', function () {
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: latLng
});
$http.get('http://#ip/elodieService/evenements/', {
params: {
fields: "adresse",
format: "json"
}
}).then(function (result) {
console.log("SUCCESS!" + result.data);
console.log(JSON.stringify(result));
$scope.adresseData = result.data;
console.log("result.data: ", result.data.adresse);
var records = result.data;
for (var i = 0; i < records.length; i++) {
var record = records[i];
var adresse = record.adresse;
console.log("adresse obtenu par web service");
console.log(adresse);
var resultat = "";
geocoder = new google.maps.Geocoder();
geocoder.geocode({'address': adresse}, callback);
function callback(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log("results[0].geometry.location");
console.log(results[0].geometry.location.latitude);
lat = results[0].geometry.location.lat();
console.log("lat");
console.log(lat);
lng = results[0].geometry.location.lng();
console.log("lng");
console.log(lng);
console.log(JSON.stringify(results));
var markerPos = new google.maps.LatLng(lat[i], lng[i]);
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: markerPos
});
} else {
console.log(status);
}
}
}
});
var infoWindow = new google.maps.InfoWindow({
content: "Here I am!"
});
google.maps.event.addListener(marker, 'click', function () {
infoWindow.open($scope.map, marker);
});
console.log(status);
}, function (error) {
console.log("Could not get location");
});
});
}
});
carte.html
<ion-view title="Carte" ng-init="init()">
<ion-content>
<div id="map" data-tap-disabled="true"></div>
</ion-content>
</ion-view>
Error:
incorrect marker location
How can I fix it?
You are passing the incorrect value to LatLng class as lat[i], lng[i]. The index position [i] is invalid.
So change your code like this:
lat = results[0].geometry.location.lat();
console.log("lat");
console.log(lat);
lng = results[0].geometry.location.lng();
console.log("lng");
console.log(lng);
console.log(JSON.stringify(results));
var markerPos = new google.maps.LatLng(lat, lng); // << Fix it here
Even, you don't have to define those lat and lng because you are getting it from a LatLng instance.
if (status == google.maps.GeocoderStatus.OK) {
console.log("results[0].geometry.location", results[0].geometry.location, JSON.stringify(results));
// No need to initialize again as the "results[0].geometry.location" is an instance of LatLng class itself
var markerPos = results[0].geometry.location;
var marker = new google.maps.Marker({
map: $scope.map,
animation: google.maps.Animation.DROP,
position: markerPos
});
}
See Geocoding Results:
results[]: {
types[]: string,
formatted_address: string,
address_components[]: {
short_name: string,
long_name: string,
postcode_localities[]: string,
types[]: string
},
partial_match: boolean,
place_id: string,
postcode_localities[]: string,
geometry: {
location: LatLng,
location_type: GeocoderLocationType
viewport: LatLngBounds,
bounds: LatLngBounds
}
}

Show a polygon and polyline on map with multiple lat long accurately

I have added multiple cities with two types of lat long in database.
Type 1. Area
Type 2. Road
Type 1 data use in polygon, and Type 2 data use in polylines. But the polygon and polyline are not show clearly like in image a blue area make through polygon and black line make through using polylines. please let me know how can i draw accurate area(need low opacity but properly fill color area) and a line(only single line)
My code is :
.controller('AllDistrictLayer', function ($scope, $state, $ionicLoading, $stateParams, $localStorage) {
$scope.loading = $ionicLoading.show({
content: 'Getting current location...',
showBackdrop: true
});
var map = null;
var mapDefaults = {
zoom: 8,
center: null,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapPosition = new google.maps.LatLng(30.722727472053084, 76.6519546508789);
mapDefaults.center = mapPosition;
map = new google.maps.Map(document.getElementById("map"), mapDefaults);
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var polyline;
var marker;
var array_data = [];
var array_path = [];
var i = 0;
var j = 0;
$(function () {
setTimeout(loadajax, 10000);
});
function loadajax() {
$.ajax({
url: "http://webapi.nuavnu.ca/api/route",
type: 'GET',
data: { type: 1 },
success: function (data) {
$ionicLoading.hide();
console.log(data);
var dbMapPoints = JSON.parse(data.AllrouteofMC);
mapdata(dbMapPoints);
}
});
$.ajax({
url: "http://webapi.nuavnu.ca/api/route",
type: 'GET',
data: { type: 2 },
success: function (data) {
$ionicLoading.hide();
initialize(JSON.parse(data.AllrouteofMC));
}
});
}
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
// ** For Type 1 Area**
function mapdata(dbMapPoints) {
$.each(dbMapPoints, function (key, index) {
var latlng = [];
var mycolor = getRandomColor();
$.when($.each($.grep(dbMapPoints, function (n, i) { return (n.MCId === index.MCId); }), function () {
latlng.push(new google.maps.LatLng(this.GPS_Lat, this.GPS_Long));
mapPoly = new google.maps.Polygon({
paths: latlng,
strokeColor: "#FF8800",
strokeOpacity: 0.00,
strokeWeight: 3,
fillColor: "blue",
fillOpacity: 0.2
});
mapPoly.setMap(map);
})).done(function () {
});
});
}
});
// ** For Type 2 Roads**
function initialize(Mapdata) {
$(function () {
$.each(Mapdata, function (key, index) {
var latlng = [];
$.when($.each($.grep(Mapdata, function (n, i) { return (n.MCId === index.MCId); }), function () {
latlng.push(new google.maps.LatLng(this.GPS_Lat, this.GPS_Long));
var flightPath = new google.maps.Polyline({
path: latlng,
geodesic: true,
strokeColor: '#000000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
})).done(function () {
});
})
});
}
});
As Harold mentioned, please share jsFiddle for your code. As far as opacity and color fill of your lines and areas is concerned, it is correctly implemented in your map. From the looks of it, you are drawing multiple intersecting polygons which are adding to layers and reducing the opacity of fillColor. You need to pass all the LatLngs in a single array and plot them together in order to get an accurate area. You can do so by also passing them as an array of unique LatLng co-ordinates as shown here.
But can't comment on the rest without the code. For a small sample, look here:

angular-google-maps center zoom multiple markers

I'm using AngularJS for Google Maps and want to dynamically center and zoom a map based on multiple markers that are dynamically loaded. This is for a Cordova app using the Ionic Framework.
Here's my view:
<ion-view title="" ng-controller="MapCtrl as vm">
<ion-content class="padding">
<google-map id="mainMap" control="vm.googleMap" draggable="true" center="vm.map.center" zoom="vm.map.zoom" mark-click="false">
<markers idKey="mainMap" fit="vm.map.fit">
<marker idKey="marker.id" ng-repeat="marker in vm.map.markers" coords="marker.coords" options="marker.options">
<marker-label content="marker.name" anchor="2 0" class="marker-labels"/>
</marker>
</markers>
</google-map>
</ion-content>
</ion-view>
Here's my controller:
angular.module('myApp.controllers', [])
.controller('MapCtrl', function($scope, $ionicPlatform) {
var vm = this;
vm.googleMap = {}; // this is filled when google map is initialized, but it's too late
vm.mapMarkers = [];
vm.arrMarkers = [
{
id: "home",
name: "home",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
},
options: {
animation: google.maps.Animation.BOUNCE
}
},
{
id: "placeAId",
name: "Place A",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
}
},
{
id: "placeBId",
name: "Place B",
coords: {
latitude:xxxxxxx, //valid coords
longitude:xxxxxxx //valid coords
}
}
];
vm.map = {
center: { //how to determine where to center???
latitude: xxxxxxx, //valid coords
longitude: xxxxxxx //valid coords
},
zoom: 12, //how to determine zoom dynamically???
fit: true,
markers: vm.arrMarkers
};
var setMapBounds = function () {
var bounds = new google.maps.LatLngBounds();
createMarkers();
var markers = vm.mapMarkers;
for(var i=0; i<markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
var map = vm.googleMap.control.getGMap();
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom()-1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom()> 15){
map.setZoom(15);
}
};
var createMarkers = function() {
var map = vm.googleMap.control.getGMap(); //vm.googleMap.control is undefined because this fire before map is initialized
angular.forEach(vm.restaurants, function(restaurant, index) {
var marker = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(restaurant.coords.latitude, restaurant.coords.longitude),
title: restaurant.name
});
vm.mapMarkers.push(marker);
});
};
$ionicPlatform.ready(function() {
setMapBounds();
});
})
So, my question is how do I center and zoom the map using multiple dynamically loaded markers? Also, how do I get an instance of googleMap.control (vm.googleMap.control) before the map is loaded?
Here's my code just in case anyone was wondering how to do this locally. This is a simple solution for what I needed and my indeed go back to angualr-google maps, but as of now this works fine in my application.
angular.module('myApp.controllers', [])
.controller('MapCtrl', function($scope) {
var vm = this;
vm.googleMap = null;
vm.mapMarkers = [];
var onSuccess = function(position) {
vm.userLocation.coords.latitude = position.coords.latitude;
vm.userLocation.coords.longitude = position.coords.longitude;
initializeMap();
};
var onError = function(error) {
alert('code: ' + error.code + '\n' + 'message: ' + error.message);
};
vm.userLocation = {
id: "home",
title: "home",
coords: {
latitude: 33.636727,
longitude: -83.920702
},
options: {
animation: google.maps.Animation.BOUNCE
}
};
vm.places = [
{
id: "78869C43-C694-40A5-97A0-5E709AA6CE51",
title: "Place A",
coords: {
latitude: 33.625296,
longitude: -83.976206
}
},
{
id: "52319278-83AA-46D4-ABA6-307EAF820E77",
title: "Place B",
coords: {
latitude: 33.576522,
longitude: -83.964981
}
}
];
var addMarkers = function() {
var userLocation = new google.maps.Marker({
map: vm.googleMap,
position: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude),
//animation: vm.userLocation.options.animation,
title: vm.userLocation.title
});
vm.mapMarkers.push(userLocation);
angular.forEach(vm.places, function(location, index) {
var marker = new google.maps.Marker({
map: vm.googleMap,
position: new google.maps.LatLng(location.coords.latitude, location.coords.longitude),
title: location.title
});
vm.mapMarkers.push(marker);
});
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < vm.mapMarkers.length; i++) {
bounds.extend(vm.mapMarkers[i].getPosition());
}
vm.googleMap.setCenter(bounds.getCenter());
vm.googleMap.fitBounds(bounds);
//remove one zoom level to ensure no marker is on the edge.
vm.googleMap.setZoom(vm.googleMap.getZoom() - 1);
// set a minimum zoom
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if (vm.googleMap.getZoom() > 15) {
vm.googleMap.setZoom(15);
}
};
var initializeMap = function() {
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 12,
center: new google.maps.LatLng(vm.userLocation.coords.latitude, vm.userLocation.coords.longitude)
};
var div = document.getElementById("map_canvas");
//var map = plugin.google.maps.Map.getMap(div, mapOptions);
vm.googleMap = new google.maps.Map(div, mapOptions);
addMarkers();
var width = screen.width;
var height = screen.height;
};
navigator.geolocation.getCurrentPosition(onSuccess, onError);
})
Your previous answer is good but doesn't include usage of the google maps directives you mentioned in the begining of the post. There is a way to do it using those directives, here is how:
Assuming we are in the directive's scope
Define scope.mapControl = {}; - this will have new access methods for map and markers
When defining your markup for the directives - for map and marker - include this control attribute to be added:
<ui-gmap-google-map center='map.center' zoom='map.zoom' control="mapControl">
<ui-gmap-marker ng-repeat="location in locations" coords="location.coordinates" options="location.markerOptions" idkey="location.id" control="mapControl">
<ui-gmap-window options="location.markerWindowOptions" closeclick="closeMarkerWindow(location.id)" show="true">
<div>{{location.description}}</div>
</ui-gmap-window>
</ui-gmap-marker>
</ui-gmap-google-map>
In your directive's event or some method:
var map = scope.mapControl.getGMap();
var markers = scope.mapControl.getGMarkers();
var bounds = map.getBounds();
for (var i = 0; i < markers.length; i++) {
bounds.extend(markers[i].getPosition());
}
map.setCenter(bounds.getCenter());
map.fitBounds(bounds);
map.setZoom(map.getZoom() - 1);

Weird behavior of angular-google-maps in Safari

Im using this project (http://angular-google-maps.org/#!/) to work with AngularJS. My code seems like:
app.js
function ( $scope, markerService ) {
var markerCollection = [];
angular.extend($scope, {
map: {
control: {},
center: {
latitude: 33.5,
longitude: -112
},
zoom: 10,
fit: true,
visible: true,
pan: true,
options: {
navigationControl: true,
scaleControl: true
}
}
});
var setMapMarkers = function (){
var markers = {};
var index = 0;
angular.forEach($scope.services, function (key) {
var service = key.address;
markerCollection.push(service);
var serviceId = service.service.id;
markers[index] = {
"latitude": parseFloat(service.latitude),
"longitude": parseFloat(service.longitude)
};
index++;
});
$scope.markers = markers;
};
setMapMarkers();
}
Im getting this behavior in Safari and its a very weird.
https://www.dropbox.com/s/r7iwlr9mnboem1d/MapGrab.mov?dl=0
Someone maybe know what can be the problem?

Resources