Reputation: 759
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;
});
}
}
});
Upvotes: 2
Views: 470
Reputation: 69915
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
Upvotes: 2
Reputation: 19987
$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.
Upvotes: 2