I am basically trying to retrieve the user's current position using the geolocation api and then pass the coordinates as parameters to an angularjs ajax call and return a custom "address" object as follows:
from the used module:
angular.module('geolocationModule', ['ng'])
.factory('geolocationService', ['$http', function geolocationService($http) {
return {
geolocationPosition : function(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
return $http.post('/bignibou/geolocation/approximateReverse/', {lat: position.coords.latitude, lng: position.coords.longitude})
.then(function(formattedAddress){
var address = {};
address.formattedAddress = formattedAddress;
return address;
},
function(data, status, headers, config){
console.log(data);
console.log(status);
});
}, errorFn, {
timeout : 10000
});
}
}
};
}]);
from calling module:
angular.module('searchEngineModule', ['ng', 'geolocationModule'])
.controller('geolocationCtrl', [ '$scope', 'geolocationService', function geolocationCtrl($scope, geolocationService) {
$scope.init = function(){
var geolocationAddress ={};
geolocationAddress = geolocationService.geolocationPosition();
console.log(geolocationAddress);
};
}]);
For some reason, my geolocationAddress object is always undefined...
Can anyone please help?
edit 1:
If I use the following async code:
var geolocationAddress ={};
geolocationService.geolocationPosition().then(function(data) {
geolocationAddress = data;
});
console.log(geolocationAddress);
Here is what I get:
TypeError: Cannot call method 'then' of undefined
at Object.$scope.init (http://localhost:8080/bignibou/js/custom/searchEngine.js:5:45)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:6541:19
at Object.Scope.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:8218:28)
at pre (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:13636:15)
at nodeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:4568:13)
at compositeLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:4191:15)
at publicLinkFn (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:4096:30)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:1042:27
at Object.Scope.$eval (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:8218:28)
at Object.Scope.$apply (https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js:8298:23) <body ng-app="searchEngineModule" ng-controller="geolocationCtrl" ng-init="init()" style="" class="ng-scope">
edit 2: Taking into account Chandermani's comments and updating to the following sorted the issue:
angular.module('geolocationModule', ['ng'])
.factory('geolocationService', ['$http', '$q', '$rootScope', function geolocationService($http, $q, $rootScope) {
function geolocationPositionP (){
var deferred = $q.defer();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
$rootScope.$apply(function(){
console.log(position);
deferred.resolve(position);
});
},
function(error){
deferred.reject(error);
},
{timeout: 10000, maximumAge: 0});
}
return deferred.promise;
}
function geolocationAddressP(){
var deferred = $q.defer();
var address = {};
var geolocationPromise = geolocationPositionP();
geolocationPromise.then(function(position){
$http.post('/bignibou/geolocation/approximateReverse/', {lat: position.coords.latitude, lng: position.coords.longitude})
.success(function(formattedAddress){
address.formattedAddress = formattedAddress;
address.latitude = position.coords.latitude;
address.longitude = position.coords.longitude;
deferred.resolve(address);
})
.error(function(data, status, headers, config){
console.log(data);
console.log(status);
deferred.reject(data);
});
});
return deferred.promise;
}
return {
geolocationAddress : function(){
return geolocationAddressP();
}
};
}])
This seems to be a async call issue. Can you try
geolocationService.geolocationPosition().then(function(data) {
geolocationAddress = data;
});
Update: The method geolocationPosition
needs to return promise or resource object due to async nature of code. Or you can even try callback method
geolocationPosition : function(){
var defer=$q.defer();
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
return $http.post('/bignibou/geolocation/approximateReverse/', {lat: position.coords.latitude, lng: position.coords.longitude})
.then(function(formattedAddress){
var address = {};
address.formattedAddress = formattedAddress;
defer.resolve(address);
},
function(data, status, headers, config){
console.log(data);
console.log(status);
defer.reject(status)
});
}, errorFn, {
timeout : 10000
});
return defer.promise
}
Read a bit about $q
http://docs.angularjs.org/api/ng.$q