I have a service like
app.factory('geolocation', function ($rootScope, cordovaReady) {
return {
getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {
navigator.geolocation.getCurrentPosition(function () {
var that = this,
args = arguments;
if (onSuccess) {
$rootScope.$apply(function () {
onSuccess.apply(that, args);
});
}
}, function () {
var that = this,
args = arguments;
if (onError) {
$rootScope.$apply(function () {
onError.apply(that, args);
});
}
}, options);
}),
getCurrentCity: function (onSuccess, onError) {
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options,function (results, status) {
var city = address_component.long_name;
});
});
}
}
});
And I want to do from a controller something like
function MainCtrl($scope, geolocation) {
geolocation.getCurrentCity(function(city){
$scope.city = city;
});
};
The getCurrentPosition works fine and the city is determined too, however I don't know how to access the city in controller.
What happens? When getCurrentCity is called, it calles getCurrentPosition to determine the gps coords. This coords are passed as arguments to the onSuccess method right? So this is quite the same I want to do in the getCurrentCity method, but I don't know how. Ones the async geocoder retrieved the city, I want to apply the new data to the onSuccess method.
Any ideas?
You are dealing with callbacks and asynchronous request. So you should use $q service. Just inject it in your service with $rootScope and cordovaReady dependency. And add the promises to your function like this
getCurrentCity: function () {
var deferred = $q.defer();
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options,function (results, status) {
var city = address_component.long_name;
$rootScope.$apply(function(){
deferred.resolve(city);
});
});
});
return deferred.promise;
}
And in your controller, do the following to handle the promise.
function MainCtrl($scope, geolocation) {
geolocation.getCurrentCity().then(function(result) { //result === city
$scope.city = result;
//do whatever you want. This will be executed once city value is available
});
};
Try this
function MainCtrl($scope, geolocation) {
$scope.city = null;
geolocation.getCurrentCity(function(city){
$scope.city = city;
if(!$scope.$$phase) {
$scope.$digest($scope);
}
});
};
Sometimes, the watcher is not always called when instanciating the controller, by forcing a digest event, if the scope is not in phase, you can go to where you want to go, I believe. Let me know if I didn't understand your question.
Oh and I don't know if i read the code properrly but it seems that you're not calling the onSuccess callback in your function: replace your getCurrentCity function by this:
getCurrentCity: function (onSuccess, onError) {
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options,function (results, status) {
var city = address_component.long_name;
if(typeof onSuccess === 'function') {
onSuccess(city);
}
});
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With