1

When I'm looping through a list of addresses, I'm able to plot the markers for all the addresses fine. But when I click on any marker, the infowindow content shows data of only the last marker. How do I solve this?

Javscript

var map ={};
map.markers = [];
map.addresses = [
    {
        'line': '2101 K St',        
        'ref_no': '160621-000005'        
    },
    {
        'line': '2131 K St',        
        'ref_no': '170708-000015'        
    },
    {
        'line': '2321 K St',        
        'ref_no': '170707-000028'
    }
];

.
.
.
map.map_object = new Map("esri_map", {
   basemap: "topo",
   center: [<lat>, <lng>],
   zoom: 12
});

var locator = new Locator("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer");
for(var i = 0; i < map.addresses.length; i++)
{
    var addr = map.addresses[i];
    var params = {
        countryCode: "US",
        maxLocations: 1,
        address: {"SingleLine": addr.line}
    };
    locator.addressToLocations(params, function(candidates){
        locatorDone(candidates, addr);
    });
}

function locatorDone(candidates, addr)
{
    if(candidates.length > 0)
    {
        var candidate = candidates[0];
        var pt = new esri.geometry.Point(candidate.location.x, candidate.location.y, new esri.SpatialReference({ 'wkid': candidate.location.spatialReference.wkid }));  
        pt = esri.geometry.geographicToWebMercator(pt);
        var symbol = new esri.symbol.PictureMarkerSymbol("/euf/assets/nebulogic/images/alert-icon.png", 21, 39);
        var html = "<h5>"+addr.line+"</h5>";            
        html += "<p>Ref#: "+addr.ref_no+"</p>";
        var infoTemplate = new esri.InfoTemplate(addr.ref_no, html);
        var graphic = new esri.Graphic(pt, symbol,'',infoTemplate);
        map.map_object.graphics.add(graphic);
        map.markers.push(graphic);            
    }
    else
    {
        console.log('not found');
    }
}

P.S: I've solved similar problems (in case of Google Maps API) by using closures. But I'm not sure how to use that in this case.

1

The addressToLocations() method is asynchronous, so the for loop iterates over all the addresses before the callback function locatorDone is executed. At which point the attr variable will have the last value from the addresses array.

To avoid this, wrap the addressToLocations() call in a function.

var locator = new Locator("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer");
for (var i = 0; i < map.addresses.length; i++) {
    var addr = map.addresses[i];
    var params = {
        countryCode: "US",
        maxLocations: 1,
        address: { "SingleLine": addr.line }
    };
    findLocations(locator, params, addr);
}
});

function findLocations(locator, params, addr) {
    locator.addressToLocations(params, function (candidates, test) {
        locatorDone(candidates, addr);
    });
}
  • I still don't think it will solve the problem because even if you port it out to another function, they asynchronous nature of the locator service will still be the same. – asprin Nov 15 '17 at 3:32
  • It will work. The correct reference to the addr variable is passed into findLocations function. When the attr variable in the for loop is set to the new value, it will not affect the attr reference set inside the findLocations function. Here is longer explanation: stackoverflow.com/questions/11488014/… – James Lawruk Nov 15 '17 at 13:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.