I'm trying to do some geolocation and based on the coordinates, call a RESTful API that returns some data. Then I want to parse this data, and finally return it I'm fairly new to angular.js and promises, therefore this code is kind of a mix of things I've seen through internet :D
I've made it all work but I'm missing the last step: returning the processed result array ("allSpots") to the original caller. What am I missing here?
.factory('wifiSpotFactory', function (WifinderModel, $q, $http) {
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
$http.get(url).then(function (response) {
var allSpots = [], data = response.data;
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}, function (error) {
console.log(error);
});
};
var wifiSpotFactory = {
loadNearSpots: function() {
var geo_options = {
enableHighAccuracy: true,
maximumAge: 50000,
timeout: 30000
};
var deferred = $q.defer();
navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, geo_options);
return deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) { return allSpots; });
}
};
return wifiSpotFactory;
} )
Then in the controller, how do I retrieve the value of the promise?
.controller('wifiListController', [
'$scope', 'wifiSpotFactory', function ($scope, wifiSpotFactory) {
$scope.spots = wifiSpotFactory.loadNearSpots();
}
])
Callback
don't have an ability to return data, you should really used promise pattern there which would have ability to return data from promise. You onGeolocationSuccess
is using callback pattern which seems return data
but actually it doesn't.
You could solve the issue just by returning the promise from the onGeolocationSuccess
method, for that you need to return $http.get
object which already returns out a promise object. In .then
of that function you would get data
that has returned from API. From .then function you could return a data
that will help you to follow the promise pattern.
Code
.factory('wifiSpotFactory', function(WifinderModel, $q, $http) {
function onGeolocationSuccess(position) {
var url = 'http://localhost:34915/api/spots?latitude=' + position.coords.longitude + '&longitude=' + position.coords.latitude;
return $http.get(url).
then(function(response) {
var allSpots = [],
data = response.data;
for (var i = 0; i < data.length; i++) {
var newSpot = new WifinderModel.wifiSpot(data[i].id, data[i].name, data[i].password, data[i].address);
allSpots.push(newSpot);
}
return allSpots;
}, function(error) {
console.log(error)
});
};
var wifiSpotFactory = {
loadNearSpots: function() {
//..other code as is..to make solution cleaner removed that part.
//return promise to follow promise chain
return deferred.promise
.then(onGeolocationSuccess)
.then(function(allSpots) {
return allSpots;
});
}
};
return wifiSpotFactory;
})
Controller
.controller('wifiListController', ['$scope', 'wifiSpotFactory',
function ($scope, wifiSpotFactory) {
wifiSpotFactory.loadNearSpots().then(function(data){
$scope.spots = data; //data will be available inside `.then` which promise resolve/reject
});
}
])