Search code examples
javascriptangularjsgeocodingangular-promisedeferred

AngularJS - not getting return value to controller or view


I'm doing a geolocation and reverse geocoding application. Function is bound to a button-click to call a function in my controller to my service. The service works somewhat, it's getting values but I cannot get it to return the value to my controller.

I previously had some more issues with promises and returns and some of it I solved but obviously not all. Help is appreciated.

My service 'geoService':

(function() {
    'use strict';
    angular.module('JourneyApp').factory('geoService',
    [
        '$q',
        function($q) {
            var geoServiceFactory = {};

            function getLocation(location) {

                var deferred = $q.defer();

                if (navigator.geolocation) {
                    navigator.geolocation.getCurrentPosition(showPosition, error);

                } else {
                    console.log("No support for Geolocation");
                    deferred.reject(false);
                }
                return deferred.promise;
            }
            function error(error) {
                console.log(error);
            }

            function showPosition(position) {

                var deferred = $q.defer();
                var geocoder = new google.maps.Geocoder();
                var coords = position.coords;
                var latlng = { lat: parseFloat(coords.latitude), lng: parseFloat(coords.longitude) };

                geocoder.geocode({ 'location': latlng },
                    function (results, status) {
                        if (status === google.maps.GeocoderStatus.OK) {
                            console.log(results);
                            if (results[0]) {
                                var formattedAddress = results[0].formatted_address;
                                console.log(formattedAddress);
                                deferred.resolve(formattedAddress);
                            } else {
                                console.log("No match, sorry");
                                deferred.reject("Error");
                            }
                        } else {
                            console.log("Error, sorry");
                            deferred.reject("Error");
                        }
                    });
                return deferred.promise;
            }

            geoServiceFactory.getLocation = getLocation;
            geoServiceFactory.showPosition = showPosition;

            return geoServiceFactory;
        }
    ]);
})();

And this is my controller:

(function() {
    'use strict';
    angular.module('JourneyApp').controller('tripsController',
    [
        'tripsService', 'vehicleService', 'geoService', function(tripsService, vehicleService, geoService) {
            //'tripsService', function (tripsService) {

            var vm = this;

            // Get start geolocation
            vm.getStartLocation = function() {
                geoService.getLocation().then(function (location) {
                    vm.trip.startAdress = location;
                });
            }

            // Get stop geolocation
            vm.getStopLocation = function() {
                geoService.getLocation().then(function(location) {
                    vm.trip.stopAdress = location;
                });
            }
        }
    ]);
}());

And parts of my view:

<div class="col-md-2">
    <input ng-model="vm.trip.startAdress"/>
</div>
<div class="col-md-2">
    <button ng-click="vm.getStartLocation()">Get location</button>
</div>

What am I doing wrong here and how do I fix it?


Solution

  • As mentioned in my comment the promise created in getLocation is never resolved and thus the value never stored. The following should do the trick(replace the if in getLocation with this code):

    [...]
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function (position) {
            showPosition(position).then(function(formattedAddress) {
                deferred.resolve(formattedAddress);
            }
        }, error);
    } else {
    [...]