0

My code has two functions that pass arrays to another function. The first time I execute this, it works, the second time it doesn't.

First time (snippet of a larger function):

for (m = 0; m < totalAnimals; m++) {
    ids = mergedIDs[m];
    file = "data/" + ids + ".geojson";
    coords = arrayArray[3 * m];
    time = arrayArray[3 * m + 1];
    props = arrayArray[3 * m + 2];

    $.getJSON(file).done(function (data) { 
        $(data).each(function () {
            coords.push(data.geometry.coordinates); 
            time.push(data.properties.time);
            id = data.properties.id;
            species = data.properties.species;
            sex = data.properties.sex;
            props.push(id, species, sex);
        });
    }).done(function () {
        makeTrack(coords, time, props);
        coords = []; // clearing in between rounds
        time = [];
        props = [];
    }).fail(function () {
        console.log(ids + "multipointCoords not populated");
    });

}

The code above successfully passes the three arrays (coords, time, props) to the makeTrack function:

    function makeTrack(multipointCoords, tracksTime, properties) {

        // parse properties array to assign to features
        var id = properties[0],
            species = properties[1],
            sex = properties[2];

        // setup OpenLayers structure and style assignment
        var trackSource = new ol.source.Vector(); // create an empty source instance

        var lineString = new ol.geom.LineString([ // create a linestring geometry from the GeoJSON data for the tracks
            ol.proj.fromLonLat(multipointCoords[0][0])
        ]);

        var icon = new ol.geom.Point( // create a point geometry from the GeoJSON data for the header icons
            ol.proj.fromLonLat(multipointCoords[0][0])
        );

etc. Everything is great so far. Later in that function I call

       segmentConstruction(multipointCoords);

and then

      function segmentConstruction(multipointCoords) {
            length = multipointCoords[0].length;

            if (i < length) {
                var timer;

                prevCoord = ol.proj.fromLonLat(multipointCoords[0][i - 1]);
                currCoord = ol.proj.fromLonLat(multipointCoords[0][i]);
                ...

I am getting the error:

TypeError: multipointCoords[0] is undefined

I did read this Javascript passing array as parameter to function, but I do not understand the difference between passing references and passing values.

According to Passing an array as parameter in JavaScript, arrays can be passed.

EDIT the arrays are two-dimensional because they are arrays of [lon,lat].

Community
  • 1
  • 1
interwebjill
  • 920
  • 13
  • 38
  • 2
    The dimensionality is irrelevant. But you're doing async stuff *inside a loop* that *will not stop* just because you're doing async stuff inside it. – Dave Newton Oct 30 '15 at 20:18
  • If all of your variables inside the for loop were defined with `let`, the problem would likely go away, however that's not supported by all browsers. – Kevin B Oct 30 '15 at 20:20
  • The problem here is your callback passed to .done closes around the `coords` variable, and passes the value of it to the next function, which is a reference to an array that was defined in the ***last*** iteration of the for loop. Then, each time .done callback gets called, for each iteration, they're acting upon the same array, the one created in the last iteration. This would surely cause unexpected results, possibly even the error you've come across. – Kevin B Oct 30 '15 at 20:26
  • @DaveNewton What do you mean by "closes" around the coords variable? I am not getting any errors or unexpected results in the makeTrack function, except perhaps the issue I present here: that even though I can use the coords/multipointCoords array in the makeTrack function, I can't pass it from there on to another function (segmentConstruction). – interwebjill Oct 30 '15 at 20:33
  • eh, you can ingore the "closes" around the coords var statement, it's really not important. What is important is that it's accessing the value of that variable, **after** the for loop as completed. It will contain the array generated on the last iteration, for all done callbacks. each callback won't have it's own array. – Kevin B Oct 30 '15 at 20:35
  • How are you creating the `totalAnimals` variable? – Kevin B Oct 30 '15 at 20:38
  • possible duplicate: http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example?rq=1 – Kevin B Oct 30 '15 at 20:39
  • @KevinB I see what you are saying, but I don't think that is the problem I am having. The function makeTrack takes all of the (totalAnimals = 63) 63 coords arrays that I create and processes them just fine. It's just that when I proceed to continue to try to pass the coords array forward to segmentConstruction, I get the TypeError. If I clear out the `length = multipointCoords[0].length;` line by, say, giving it an integer value, I get a TypeError on multipointCoords[0][i]. – interwebjill Oct 30 '15 at 20:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/93838/discussion-between-kevin-b-and-interwebjill). – Kevin B Oct 30 '15 at 20:59

0 Answers0