Search code examples
javascriptdatamaps

JavaScript Loops when calling Async


Problem: JavaScript is able to successfully draw several arcs on the screen, but they disappear when run. I am running a simple loop calling the ARC function, I don't get it!?

All I want to do is run each call step by step and sleep! This could be done in any language outside of JavaScript with ease, its a simple procedural Loop.

The problem is my graph shows up for a split second before disappearing. However if I trace through the code via JavaScript debugger it works until it disappears again!

Frustrated! I tried to wrap this with a timeOut, so I can sleep to show a slow animation. What on earth is going on my friends, is this a bug in JavaScript or are my fundamentals not there. I can't understand the codeflow when its so logically written.

https://jsfiddle.net/nd6gktmf/

var array_length = attack_list.length;
//EDITED: declare local variables
var coordinates,
    origin_longitude,
    origin_latitude,
    dest_longitude,
    dest_latitude;

for(var i=0; i < array_length; i++) {
   coordinates = attack_list[i];
   //EDITED: consider using dot notation
   origin_longitude = coordinates.origin.longitude;
   origin_latitude = coordinates.origin.latitude;
   dest_longitude = coordinates.destination.longitude;
   dest_latitude = coordinates.destination.latitude;

   draw_arc(origin_longitude, origin_latitude, dest_longitude, dest_latitude);
}    

This Works only in debug mode! What the....

function draw_arc(origin_longitude, origin_latitude, dest_longitude, dest_latitude) {
    var data_to_map = 
        [{ 
            origin: {
                latitude: origin_latitude,
                longitude: origin_longitude
            },
            destination: {
                latitude: dest_latitude,
                longitude: dest_longitude 
            }
        }]; 

   console.log("****** Begin******");
   console.log(origin_longitude);
   console.log(origin_latitude);
   console.log(dest_longitude);
   console.log(dest_latitude);
   console.log("****** End ******");

   election.arc(data_to_map, {strokeWidth: 2});
}

Solution

  • As Kevin pointed out: Delete all the javascript code you added to your question (of course leave your data: election and attack_list) and replace it with:

    // loop over the attack_list
    attack_list.forEach(function(attack_item, i){
      // now attack_item is one item from the array, i is the index in the array
      // we set up a timer FOR EACH item in the array
      setTimeout(function(){
        // we make an empty array, because election.arc needs an array,
        // eventhough we'll only send 1 item in it, we wrap it in an array
        var draw_list = [];
        draw_list.push(attack_item);
        // put the item into the array
        election.arc(draw_list,{strokeWidth: 2});
      }, i*2000);
      // note: the time is i*2000ms = i*2s
      // the "1st" item in attack_list is at index 0
      // so 0*2000=0 => it'll start drawing it immediately (t=0)
      // it animates for about 1s (t=1)
      // the last drawn line is still displayed (t=1..2)
      //
      // t=2: now the timer for the "2nd" item (i=1) starts drawing
      // but because we created a new empty array and only added the 2nd item
      // into it, when it draws, it erases everything that we drew before
      // and now you only see the 2nd item is getting animated.
      // etc...
    });
    

    https://jsfiddle.net/flocsy/nd6gktmf/3/