0

Here is my sample code

var selected_path = [];

            for (var i = 0; i <path.length-1; i++) {
                    var request = {
                    origin: path[i],
                    destination: path[i+1],
                    travelMode: google.maps.DirectionsTravelMode.WALKING

                }

                directionsService.route(request, function(results, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        selected_path = selected_path.concat(results.routes[0].overview_path);

                    }
                })

            }
            console.log(selected_path);  // slected_path in console is []
            poly.setPath(selected_path);
            poly.setMap(map);

In this situation selected_path in console is []. When I add alert(i) line before console.log(selected_path). Here is code after addition:

var selected_path = [];

            for (var i = 0; i <path.length-1; i++) {
                    var request = {
                    origin: path[i],
                    destination: path[i+1],
                    travelMode: google.maps.DirectionsTravelMode.WALKING

                }

                directionsService.route(request, function(results, status) {
                    if (status == google.maps.DirectionsStatus.OK) {
                        selected_path = selected_path.concat(results.routes[0].overview_path);

                    }
                })

            }
            alert(i)   ////// ADDED ONE LINE
            console.log(selected_path); /// selected_path in console has proper value
            poly.setPath(selected_path);
            poly.setMap(map);

Variable i is showing like an alert on screen and variable selected_path has proper value. Could somebody explain it to me, because I dont't get it. To clarify it works in firefox, probably not in chrome.

4
  • "i" is in the scope of the loop. to use it outside, declare it before the loop and use the loop like "for (i = 0;...)" without the "var" statement. Commented May 20, 2012 at 12:22
  • 1
    @StanWiechers: You're wrong. There is no block scope in JavaScript Commented May 20, 2012 at 12:23
  • JavaScript has no block scope unless your engine supports let and you use let i = 0; in the loop header. Commented May 20, 2012 at 12:23
  • thanks guys. I might have misunderstood the question, I thought "i" was undefined, that would have been the only adhoc idea I had Commented May 20, 2012 at 12:34

2 Answers 2

4

I think this is due to the asynchronous behaviour of the directionsService.route method. It calls the callback function after the ajax call has finished.

So when you show the alert, execution of the code afterwards (console.log) is posponed until you click the OK button. That is enough time for the ajax call to finish and populate the selected_path variable. In the version without the alert there is no such delay so the ajax call has not finished yet and most likely could not have populated selected_path before the console.log runs.

To fix this you can do two things:

  1. Put the code that you want to execute after selected_path has been filled in the callback function as well.
  2. Start a timeout to check if it has filled and only run the code when it has.

So the first solutions would be to do this:

 directionsService.route(request, function(results, status) {
   if (status == google.maps.DirectionsStatus.OK) {
      selected_path = selected_path.concat(results.routes[0].overview_path);

      alert(i)   ////// ADDED ONE LINE
      console.log(selected_path); /// selected_path in console has proper value
      poly.setPath(selected_path);
      poly.setMap(map);
    }
  })

The second would be this:

 directionsService.route(request, function(results, status) {
   if (status == google.maps.DirectionsStatus.OK) {
      selected_path = selected_path.concat(results.routes[0].overview_path);
    }
  })

  (function test() {
    if (selected_path.length > 0) {
      alert(i)   ////// ADDED ONE LINE
      console.log(selected_path); /// selected_path in console has proper value
      poly.setPath(selected_path);
      poly.setMap(map);
    } else {
      setTimeout(test, 200);
    }
  })();

If possible I'd use the first one.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 This would be the main issue, yes. I missed the function (and I even looked for functions before answering).
1

It's because you're setting selected_path in asynchronous callback. The alert(i) takes enough time to evaluate the asynchronous callback, that is why it works. But you can't rely on it (as well as you can't rely on setTimeout(function(){console.log(selected_path);}, 0), which should work the same), because the asynchronous call could take a long time.

The solution is to put all the code working with selected_path and all the code, that should be evaluated after it into the callback, like this:

directionsService.route(request, function(results, status) {
     if (status == google.maps.DirectionsStatus.OK) {
          var selected_path = selected_path.concat(results.routes[0].overview_path);
          poly.setPath(selected_path);
          poly.setMap(map);
          // ...
     }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.