Search code examples
javascriptangularjscallbackionic-frameworksteroids

AngularJS: Callbacks defined properly?


I'm trying to print a list of objects showing their names and the distance between its and the users location. I do retrieve the data via GET and calculate the distance based on the latitudes and longitudes. However, the length of my scope-array remains 0. I guess there's something wrong with my callback architecture but i can't seem to figure it out.

Controller:

angular.module('ionicApp', ['ionic']).controller('objectCtrl', function($scope, $http) {
$scope.objects = [];
$http.get('http://url.com/getobjects.php').then(function (resp) {
    for (var i = 0; i < resp.data.length; i++) {
        getDistance(resp.data[i].lat, resp.data[i].lng, (function(index){
            return function(dist){
                $scope.objects[index] = {
                    name: resp.data[index].name,
                    distance: dist
                };
            }
        })(i));
    }
}, function (err) {
    console.error('ERR', err);
    alert("error");
});

GetDistance:

function getDistance(lat2, lon2, callback) {
    navigator.geolocation.getCurrentPosition(function onSuccess(position) {
        var lat1 = position.coords.latitude;
        var lon1 = position.coords.longitude;
        var radlat1 = Math.PI * lat1 / 180;
        var radlat2 = Math.PI * lat2 / 180;
        var radlon1 = Math.PI * lon1 / 180;
        var radlon2 = Math.PI * lon2 / 180;
        var theta = lon1 - lon2;
        var radtheta = Math.PI * theta / 180;
        var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
        dist = Math.acos(dist);
        dist = dist * 180 / Math.PI;
        dist = dist * 60 * 1.1515;
        dist = dist * 1.609344;
        callback(dist);
    }, function onError(error) {
        alert("no location found:"+ error);
    });
}

Any ideas what's wrong with my code? Thanks.


Solution

  • Looks like getDistance callback appears out of the $digest cycle. So you should try to kick it off manually:

    $scope.objects[index] = {
        name: resp.data[index].name,
        distance: dist
    };
    $scope.$apply();
    

    or using $timeout service:

    getDistance(resp.data[i].lat, resp.data[i].lng, (function (index) {
        return function (dist) {
            $timeout(function() {
                $scope.objects[index] = {
                    name: resp.data[index].name,
                    distance: dist
                };
            });
        }
    })(i));