-1
for (var i = 0; i < stops.length; i++) {
    var code = stops[i].atcocode;
    var name = stops[i].common;
    var direction = stops[i].direction;
    var alertMessage = "View departures for " + stops[i].common + (directionText !== 'Unknown' ? (" (facing " + directionText + ")") : "") + "?";

    this.map.addMarker({
        icon: icon,
        position: new plugin.google.maps.LatLng(stops[i].latitude, stops[i].longitude)
    }, function(markerCallback) {
        markerCallback.code = code;
        markerCallback.name = name;
        markerCallback.direction = direction;
        markerCallback.alert = alertMessage;

        markerCallback.addEventListener(plugin.google.maps.event.MARKER_CLICK, function(clickedMarker) {
            alert(markerCallback.name);
        });

        _this.busStopMarkers.push(markerCallback);
    });
}

JavaScript closure inside loops – simple practical example

I have viewed the question above and am not sure how to apply the same answer logic into my scenario. Could somebody please show me an example as to how I can make the alert show the indexed item in the array rather than the last one?

Community
  • 1
  • 1
jskidd3
  • 4,609
  • 15
  • 63
  • 127

2 Answers2

1

Create a callback factory:

function createCallback(_this, code, name, direction, alertMessage) {
    return function(markerCallback) {
        markerCallback.code = code;
        markerCallback.name = name;
        markerCallback.direction = direction;
        markerCallback.alert = alertMessage;

        markerCallback.addEventListener(plugin.google.maps.event.MARKER_CLICK, function(clickedMarker) {
            alert(markerCallback.name);
        });

        _this.busStopMarkers.push(markerCallback);
    };
}

Then use it to create a function inside your loop:

for (var i = 0; i < stops.length; i++) {
    var code = stops[i].atcocode;
    var name = stops[i].common;
    var direction = stops[i].direction;
    var alertMessage = "View departures for " + stops[i].common + (directionText !== 'Unknown' ? (" (facing " + directionText + ")") : "") + "?";

    var callback = createCallback(_this, code, name, direction, alertMessage);

    this.map.addMarker({
        icon: icon,
        position: new plugin.google.maps.LatLng(stops[i].latitude, stops[i].longitude)
    }, callback);
}
Andrew Vermie
  • 623
  • 3
  • 8
0

You can create an anonymous function like this:

for (var i = 0; i < stops.length; i++) {
    (function(me, stop){ // Use the stop as an argument, this function is directly called
        var code = stop.atcocode;
        var name = stop.common;
        var direction = stop.direction;
        var alertMessage = "View departures for " + stop.common + (directionText !== 'Unknown' ? (" (facing " + directionText + ")") : "") + "?";

        me.map.addMarker({
            icon: icon,
            position: new plugin.google.maps.LatLng(stop.latitude, stop.longitude)
        }, function(markerCallback) {
            markerCallback.code = code;
            markerCallback.name = name;
            markerCallback.direction = direction;
            markerCallback.alert = alertMessage;

            markerCallback.addEventListener(plugin.google.maps.event.MARKER_CLICK, function(clickedMarker) {
                alert(markerCallback.name);
            });

            _this.busStopMarkers.push(markerCallback);
        });
    })(this, stops[i]); // Pass the stop

}
Niels
  • 48,601
  • 4
  • 62
  • 81
  • Can't get this code to run. Would it make a difference if it were inside an object method? Can't think why but for some reason it's not throwing a specific error it's just failing to even create an instance of the class – jskidd3 May 13 '14 at 17:29
  • The problem was I didn't pas the this, because the `this` in the anonymous function would not refer to the same object. – Niels May 13 '14 at 17:37
  • OP is already using `_this`, you seem to have exchanged that for a `me`. One of them should be enough. – Bergi May 13 '14 at 17:53
  • Agree but I don't know for sure where `_this` is referring. – Niels May 13 '14 at 17:57