So I used GeoFire and AngularFire for populate my ng-repeat item lists. There is an ionic pull to refresh list. So user pull it and get the current updated location and refresh the list (recall the GeoFire to re-populate the list).
$scope.doRefresh = function() {
if ($scope.doneLoading) {
$scope.useCurrentLocation().then(function() {
$scope.userCurrentLocation = {
lat: geoLocation.getGeolocation().lat,
lng: geoLocation.getGeolocation().lng
}
angular.forEach($scope.tasks, function(child) {
child.$destroy();
});
setupTaskListing();
$scope.$broadcast('scroll.refreshComplete');
})
}
}
function setupTaskListing() {
console.log("setupTask is being called");
if ($scope.tasks.length > 0) {
console.log("task is not empty!");
$scope.tasks = [];
}
if ($scope.query) {
console.log("$scope.query is not empty:" + $scope.query);
$scope.query.cancel();
}
var radiusInMiles = ($scope.radius) * 1.60934;
$scope.query = taskService.setGeoQuery($scope.userCurrentLocation.lat, $scope.userCurrentLocation.lng, radiusInMiles); //My service to set Geo Query.
var geoQueryCallback = $scope.query.on("key_entered", "SEARCH:KEY_ENTERED");
}
$scope.$on("SEARCH:KEY_ENTERED", function(event, key, location, distance) {
//my service to get a single task. It return a firebase object. So I use $loaded
var task = taskService.getTask(key);
task.$loaded().then(function(data) {
data.distance = parseInt(distance * 0.621371192);
data.id = data.$id;
$scope.tasks.push(data);
});
});
As you see the code above, pretty straight forward. doRefresh() call setupTaskListing(). And it setup geoQueryCallback that when key entered event fire, push new data into the $scope.tasks array. So it works.
But the problem for this GeoFire structure is...I have no idea when ALL the tasks finished entering the radius...So I can not set up a loader and prompt when there is NO data inside the radius. When there is NO data enter, the key_entered event never fire, so I will never know if there is data or not. It can be either NO data or GeoFire still loading. If I put the loader.hide() method inside $scope.$on, it will never fire when there is actually no data. So my screen will forever loading. The ideal UX should be stop loading and prompt people to increase the search radius. If I put the loader.hide() outside the $scope.$on with a set $timeout to call it. GeoFire take longer to load the data before $timeout run. So user will prompt the change radius screen then flash back to the actual list. Bad UX again. So...what is my option here? Is there some kind of promise I can use in GeoFire?