2

I couldn't figure out this problem. My question is why I cannot resolve responses. And I cannot use the responses in my controller. But I get 6 responses as empty. Please open console and push "Get Result" button under the google map. You will see undefined array.

here is plunker

 getGoogleDirection.getData(response,$scope.mymap).then(function(res){
                console.log(res); // **it returns undefined elements**
            });

And here are services.

    App.factory('setData',function($q){
    return {
        getData:function(array){
            var deferred = $q.defer();
            var newArray = [];
            angular.forEach(array,function(firstBlocks,key){
                var dummy = firstBlocks.chunk(9);
                angular.forEach(dummy,function(last,key2){
                    if(key2!=0){
                        dummy[key2].unshift(dummy[key2-1][dummy[key2-1].length-1]);
                    }
                });
                newArray.push(dummy);
            });
            deferred.resolve(newArray);
            return deferred.promise;
        }
    };
}); 
App.factory('getGoogleDirection',function($q){
    return {
        getData:function(array,mymap){
            var distances = [];
            var promises = []
            angular.forEach(array,function(object,key){
                angular.forEach(object,function(array2,key2){
                    promises.push(getDirection(array2));
                });
            });
            function getDirection(array){
                var wayPoints = [];
                var start = array[0];
                var finish = array[array.length-1];
                array.pop();
                array.shift();
                angular.forEach(array,function(item,key){
                    wayPoints.push({
                        location:new google.maps.LatLng(parseFloat(item.lat),parseFloat(item.lng)),
                        stopover:true
                    });
                });
                calcRoute(new google.maps.LatLng(parseFloat(start.lat),parseFloat(start.lng)), wayPoints, new google.maps.LatLng(parseFloat(finish.lat),parseFloat(finish.lng)));
            }
            function calcRoute(start,waypoints,end) {
                var directionsDisplay;
                var directionsService = new google.maps.DirectionsService();
                directionsDisplay = new google.maps.DirectionsRenderer();
                directionsDisplay.setMap(mymap);
                    var request = {
                        origin:start,
                        destination:end,
                        waypoints:waypoints,
                        optimizeWaypoints: false,
                        travelMode: google.maps.TravelMode.DRIVING,
                        avoidHighways:false,
                        avoidTolls:false
                    };
                var deferred = $q.defer();
                return directionsService.route(request, function(response, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        directionsDisplay.setDirections(response);
                        deferred.resolve(response);
                    }else{
                        deferred.reject(response);
                        alert('Error');
                    }
                    return deferred.promise;
                });
            }
            return $q.all(promises).then(function(res){
                return res;
            });
        }
    }
});
Oğuz Can Sertel
  • 749
  • 2
  • 11
  • 26
  • You should take a look at [this](https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns) and [this](http://stackoverflow.com/questions/28764182/avoiding-the-deferred-anti-pattern). – Henrique Barcelos Jun 08 '15 at 19:27
  • Thank you for the info. I will read it. I have updated the question. Could you check it out ? – Oğuz Can Sertel Jun 08 '15 at 21:14

2 Answers2

2

When the promise is resolved it provides the resolved data in its callback function. In your code you are not using that.

Change this piece of code

              var dist = [];
              angular.forEach(data, function (d) {
                if (d) dist.push(d);
              });
              console.log(dist);
              return dist;

Take a look here http://plnkr.co/edit/dmlhpWKUxL7CLb1ej8FV?p=preview

ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
2

$q.all(promises) finishes when all promises are finished, however the promises array does not contain promises at all. What is added to the promises array is the return value of directionsService.route, which is not a promise. When you give $q a non promise to resolve it acts like a promise that is resolved to that same value. For example:

      $q.when(1).then(function(x) {
        alert(x);
      });

Will alert '1', even though 1 is not a promise.

So what you need to do is return a promise that resolves when in the route callback status == google.maps.DirectionsStatus.OK. When your promises resolve properly you can use distances.

However, it is much better to resolve your promises with a distance, so the end result would be something like this:

var result = $q.deferred();
directionsService.route(request, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
        var distances = [];
        angular.forEach(response.routes[0].legs,function(leg){
              distances.push(leg.distance.value);
          });
        directionsDisplay.setDirections(response); // 
        result.resolve(distances);
    }else{
        result.reject('Google dan veri alımında hata yaşandı');
    }
});
return result.promise;

You can then use it like this: $q.all(promises).then(function(allDistances) { ... }, where allDistances is a 2d array of distances, whereas the first index corresponds to the route and the second index to the leg.

Lodewijk Bogaards
  • 19,777
  • 3
  • 28
  • 52
  • Thank you for the answer. Could you edit the plunker ? – Oğuz Can Sertel Jun 08 '15 at 20:00
  • Actually I call directionservice more than one time in this example. So you just return only one element for the loop which is promises.push(getDirection(array2)); – Oğuz Can Sertel Jun 08 '15 at 20:04
  • I have updated the question and plunker :) I still cannot get responses. – Oğuz Can Sertel Jun 08 '15 at 21:12
  • I have given you the correct answer to what your problem was (your promises were not promises), now you should be able to solve it by yourself. Stackoverflow is not a place where other people code for you, but a place you can ask questions. Perhaps ShankarSangoli is willing. Good luck. – Lodewijk Bogaards Jun 08 '15 at 21:53
  • Thank you so much for the answer but this is not solution. I have updated question. – Oğuz Can Sertel Jun 09 '15 at 07:29
  • Yes. I think I understand the problem. I defined $q.defer() only one time for the loop. in fact I had to define the $q.defere for each loop. I got it. Thank you. You are amazing. You helped me lot. – Oğuz Can Sertel Jun 09 '15 at 08:33