Why is my function getting 0 results?
Hey, what have I got here like 3 functions that work together. But the problem is the last one is called itnt iteration because it sees it as an empty array. Funny, when I do the console.log()
whole object, it has data in this array, but when I register only this element of the array from this object, it is empty. Why?
You are the encoder here: http://codepen.io/anon/pen/NqoYjd?editors=101
This is how it looks:
getPlacesInArea: function($scope, types, callback) {
for (var key in types) {
if (types.hasOwnProperty(key) && types[key].checked) {
this.getPlace($scope, key);
}
}
callback($scope);
},
So what's going on here, I am just loading the data from the api into the scope.
getAttractionsInArea: function($scope, typesValue) {
placesService.getPlacesInArea($scope, typesValue, this.showAttractionMarkers);
},
showAttractionMarkers: function($scope) {
placesService.showPlacesMarkers($scope.map, $scope.attractionsMarkers);
}
Here is where this place is called getPlacesInArea
. The getAttractionsInArea
i is also passed as a callback method showAttractionMarkers
.
showPlacesMarkers: function(map, markers) {
if (typeof map != 'undefined') {
for (var key in markers) {
if (markers.hasOwnProperty(key)) {
mapService.setMapForMarkers(markers[key].items, map);
}
}
} else {
for (var type in markers) {
if (markers.hasOwnProperty(type)) {
mapService.setMapForMarkers(markers[type].items, null);
}
}
}
},
Here we are in this function, if I do console.log(markers)
I can see that [type] .items markers have elements. But if I do console.log(markers[type].items)
, the array is empty. Why is this? how can i fix this?
Here console.log(markers);
Object {food: Object, art_gallery: Object, museum: Object, night_club: Object}
And here is an example of a food object
food: Object
checked: true
icon: null
items: Array[20]
0: MarkerWithLabel
1: MarkerWithLabel
2: MarkerWithLabel
3: MarkerWithLabel
4: MarkerWithLabel
5: MarkerWithLabel
6: MarkerWithLabel
7: MarkerWithLabel
8: MarkerWithLabel
9: MarkerWithLabel
10: MarkerWithLabel
11: MarkerWithLabel
12: MarkerWithLabel
13: MarkerWithLabel
14: MarkerWithLabel
15: MarkerWithLabel
16: MarkerWithLabel
17: MarkerWithLabel
18: MarkerWithLabel
19: MarkerWithLabel
length: 20
__proto__: Array[0]
__proto__: Object
var $scope,
objectByString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1');
s = s.replace(/^\./, '');
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
o = o[k];
} else {
return;
}
}
return o;
},
getMarkersPath = function(amountPath) {
var paths = amountPath.split('.');
return paths[paths.length - 1] + 'Markers';
},
getAttractionsInArea = function($scope, typesValue) {
getPlacesInArea($scope, typesValue, 'filters.location.attractions', 'fa-star', showAttractionMarkers);
},
showAttractionMarkers = function($scope) {
var checked = $scope.searchData.filters.location.attractions.checked;
if (checkPropertyExistence($scope, ['attractionsMarkers'])) {
showPlacesMarkers($scope.map, $scope.attractionsMarkers, checked);
}
},
clearPlacesMarkers = function($scope, markersPath) {
if (checkPropertyExistence($scope, [markersPath])) {
var types = $scope[markersPath];
for (var type in types) {
if (types.hasOwnProperty(type)) {
setMapForMarkers(types[type].items, null);
}
}
}
},
showPlacesMarkers = function(map, markers, checked) {
if (typeof map != 'undefined' && checked) {
for (var key in markers) {
if (markers.hasOwnProperty(key) && markers[key].checked) {
setMapForMarkers(markers[key].items, map);
}
}
} else {
for (var type in markers) {
if (markers.hasOwnProperty(type) && markers[type].checked) {
setMapForMarkers(markers[type].items, null);
}
}
}
},
getPlacesInArea = function($scope, types, propertyPath, icon, callback) {
var markersPath = getMarkersPath(propertyPath);
this.clearPlacesMarkers($scope, markersPath);
addToProperty($scope.searchData, propertyPath + '.amount', 0);
$scope[markersPath] = types;
types = $scope[markersPath];
if (typeof $scope.map != 'undefined') {
for (var key in types) {
if (types.hasOwnProperty(key) && types[key].checked) {
this.getPlace($scope, key, propertyPath, icon);
}
}
callback($scope);
}
},
getPlace = function($scope, key, propertyPath, icon) {
var service = new google.maps.places.PlacesService($scope.map),
request = {
location: new google.maps.LatLng($scope.searchData.location.lat, $scope.searchData.location.lon),
radius: 700,
types: [key]
},
markersPath = getMarkersPath(propertyPath);
service.nearbySearch(request, function(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var markers = [],
amount = objectByString($scope.searchData, propertyPath + '.amount');
for (var i = 0; i < results.length; i++) {
var place = results[i];
var typeIcon = null;
if (checkPropertyExistence($scope, [markersPath, key, 'icon'])) {
typeIcon = objectByString($scope, markersPath + '.' + key + '.icon');
}
var markerIcon = (typeIcon !== null ? typeIcon : (icon !== null ? icon : place.icon)),
marker = addMarker(place.geometry.location, null, markerIcon);
addInfoBubble(marker, place.name, place.vicinity.substr(0, 70), markerIcon, $scope.map, key.replace(/_/g, ' '));
markers.push(marker);
if (checkPropertyExistence($scope, [markersPath, key, 'items'])) {
$scope[markersPath][key]['items'] = markers;
}
}
addToProperty($scope.searchData, propertyPath + '.amount', amount + markers.length);
}
})
},
addToProperty = function($searchData, $keyString, $value) {
var keys = $keyString.split(".");
lastKeyIndex = keys.length - 1;
for (var i = 0; i < lastKeyIndex; ++i) {
key = keys[i];
if (!(key in $searchData))
$searchData[key] = {};
$searchData = $searchData[key];
}
$searchData[keys[lastKeyIndex]] = $value;
},
checkPropertyExistence = function(obj, paths) {
for (var i = 0; i < paths.length; i++) {
if (!obj || !obj.hasOwnProperty(paths[i])) {
return false;
}
obj = obj[paths[i]];
}
return true;
},
addMarker = function(point, map, icon, color) {
if (typeof color == 'undefined') {
color = "#000000";
}
return new MarkerWithLabel({
position: point,
map: map,
icon: ' ',
labelContent: '<i class="fa ' + icon + ' fa-2x" style="color:' + color + ';"></i>',
labelAnchor: point
});
},
addInfoBubble = function(marker, title, content, icon, map, additionalInfo) {
if (typeof icon == 'undefined') {
icon = "fa-map-marker";
}
if (typeof additionalInfo == 'undefined') {
additionalInfo = "";
}
var bounds = map.getBounds(),
myOptions = {
content: "<div class='info'>" +
"<div class='infoBubble'>" +
"<h4><i class='fa " + icon + "'></i> " + title + " <small>" + additionalInfo + "</small></h4>" +
"<p>" + content + "</p>" +
"</div>" +
"</div>",
disableAutoPan: true,
position: new google.maps.LatLng(bounds.getNorthEast().lat(), bounds.getSouthWest().lng()),
isHidden: false,
closeBoxURL: ""
};
var infobox = new InfoBox(myOptions);
google.maps.event.addListener(marker, 'mouseover', function() {
infobox.open(map);
});
google.maps.event.addListener(marker, 'mouseout', function() {
infobox.close();
});
return infobox;
},
setMapForMarkers = function(markers, map) {
var self = this;
for (var i = 0; i < markers.length; i++) {
try {
markers[i].setMap(map);
} catch (e) {
}
}
};
function initialize() {
$scope = {
searchData: {
location: {
lat: 40.722840,
lon: -73.999585
}
},
filters: {
location: {
attractions: {
checked: true
}
}
}
};
var mapProp = {
center: new google.maps.LatLng(40.722840, -73.999585),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
$scope.map = new google.maps.Map(document.getElementById("googleMap"), mapProp);
$scope.getAttractionsInArea = function() {
var value = {
food: {
checked: true,
icon: null,
items: []
},
art_gallery: {
checked: true,
icon: null,
items: []
},
museum: {
checked: true,
icon: null,
items: []
},
night_club: {
checked: true,
icon: null,
items: []
}
};
getAttractionsInArea($scope, value);
};
$scope.showAttractionMarkers = function() {
showAttractionMarkers($scope);
};
$scope.getAttractionsInArea();
}
function show(element) {
element.checked ? $scope.filters.location.attractions.checked = true : $scope.filters.location.attractions.checked = false;
$scope.showAttractionMarkers();
}
initialize();
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/infobox/src/infobox.js"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerwithlabel/src/markerwithlabel.js"></script>
<label>
<input type="checkbox" value="check" id="xxx" onchange="show(this)" />Show markers
</label>
<div id="googleMap" style="width:500px;height:380px;"></div>
source to share
You can show markers when the callback returns (only markers are returned) so when the food callback returns only shows food
service.nearbySearch(request, function (results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
var markers = [],
amount = objectByString($scope.searchData, propertyPath + '.amount');
for (var i = 0; i < results.length; i++) {
var place = results[i];
var typeIcon = null;
if (localStorageService.checkPropertyExistence($scope, [markersPath, key, 'icon'])) {
typeIcon = objectByString($scope, markersPath + '.' + key + '.icon');
}
var markerIcon = (typeIcon !== null ? typeIcon : (icon !== null ? icon : place.icon)),
marker = mapService.addMarker(place.geometry.location, null, markerIcon);
mapService.addInfoBubble(marker, place.name, place.vicinity.substr(0, 70), markerIcon, $scope.map, key.replace(/_/g, ' '));
markers.push(marker);
if (localStorageService.checkPropertyExistence($scope, [markersPath, key, 'items'])) {
$scope[markersPath][key]['items'] = markers;
}
}
localStorageService.addToProperty($scope.searchData, propertyPath + '.amount', amount + markers.length);
localStorageService.save($scope.searchData, "searchData");
if (checked)) {
mapService.setMapForMarkers(markers, $scope.map);
}
}
});
source to share
See comments below
You can try some kind of bootloader like this. Assuming drinks are the last property of the tokens object
function dataLoaded () {
if (markers.drinks.items.length > 1) {
showPlacesMarkers();
} else {
dataLoaded();
}
}
Simple implementation just to show you the concept. Hope it helps
source to share