1

Is there something special I need to do to access objects inside $timeout functions?

I get errors saying routes is undefined when I try and access it in the $timeout function, but outside the $timeout function (where the console log is) it logs the object and everything in it is as expected:

$scope.drawRoutes = function(routes) {
  console.log(routes);
  for (var i = 0; i < routes.length; i++) {
     $timeout(function() {
        MapService.directionsService.route(routes[i], function(response, status) {
           if (status == google.maps.DirectionsStatus.OK) {
              MapService.direction_renderers.push(new google.maps.DirectionsRenderer());
              MapService.direction_renderers[MapService.direction_renderers.length - 1].setMap(MapService.gmaps.map);
              MapService.direction_renderers[MapService.direction_renderers.length - 1].setDirections(response);
              $scope.connectors_created += 1;
              $scope.$digest();
           }
        });
     }, 1000);
   }
};
andro1d
  • 568
  • 2
  • 11
  • 20

1 Answers1

5

Here the problem is the use closure variable i within the timeout callback function... inside each callback instance i refers to the same closure instance... so when the loop is exited i has the value routes.length which results in accessing routes[routes.length] in the callbak which will be undefined.

Assuming routes is an array object, you can use the forEach() iterator function to solve the problem

$scope.drawRoutes = function (routes) {
    console.log(routes);
    angular.forEach(routes, function (route, idx) {
        $timeout(function () {
            MapService.directionsService.route(route, function (response, status) {
                if (status == google.maps.DirectionsStatus.OK) {
                    MapService.direction_renderers.push(new google.maps.DirectionsRenderer());
                    MapService.direction_renderers[MapService.direction_renderers.length - 1].setMap(MapService.gmaps.map);
                    MapService.direction_renderers[MapService.direction_renderers.length - 1].setDirections(response);
                    $scope.connectors_created += 1;
                    $scope.$digest();
                }
            });
        }, (idx + 1) * 1000);
    })
};
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Thanks, that did it. I also realized that my approach makes no sense. I'm trying to render the new route every 1 second, but my approach waits 1 second then renders all of them because all of the timeouts are called within milliseconds of eachother :-( – andro1d Sep 30 '13 at 03:03