Select to view content in your preferred language

onUpdateEnd not triggered when FeatureLayer added to map

1074
1
Jump to solution
04-10-2013 11:45 AM
JoanneMcGraw
Frequent Contributor
It appears the Map's "onUpdateEnd" event isn't always triggered when a layer is added (e.g. if I add it via a shapefile) and I'm hoping to learn why this is the case.

To illustrate my problem, I've modified the sample at http://developers.arcgis.com/en/javascript/samples/portal_addshapefile/ below. You'll need to set proxyUrl appropriately to run on your server.

The only other edits to the HTML have been to:
1. Add an "onUpdateEnd" event listener to the map that displays an alert to see if the event is being triggered (line 54); and,
2. Comment out a map.setExtent call in the addShapefileToMap function (line 143). That call WAS triggering the map's "onUpdateEnd" event, but zooming in to a newly imported shapefile is not functionality I want in my application at that time.

<!DOCTYPE HTML> <html>   <head>     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">     <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9">     <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">     <title>Add Shapefile</title>      <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/js/dojo/dijit/themes/claro/claro.css">     <link rel="stylesheet" href="http://developers.arcgis.com/en/javascript/samples/portal_addshapefile/css/app.css">     <!--[if !IE]> -->     <link rel="stylesheet" href="http://developers.arcgis.com/en/javascript/samples/portal_addshapefile/css/fileupload.css">     <!-- <![endif]-->     <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/js/esri/css/esri.css">      <script>var dojoConfig = { parseOnLoad: true };</script>     <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.4/"></script>     <script>       dojo.require("esri.map");       dojo.require("esri.layers.FeatureLayer");       dojo.require("dijit.layout.BorderContainer");       dojo.require("dijit.layout.ContentPane");        dojo.ready(pageReady);       var map;       var portalUrl = "http://www.arcgis.com";        function pageReady() {         esri.config.defaults.io.proxyUrl = "/EMAF/proxy/proxy.php";         dojo.connect(dojo.byId("uploadForm").data, "onchange", function (evt) {           var fileName = evt.target.value.toLowerCase();           if (dojo.isIE) { //filename is full path in IE so extract the file name             var arr = fileName.split("\\");             fileName = arr[arr.length - 1];           }           if (fileName.indexOf(".zip") !== -1) {//is file a zip - if not notify user             generateFeatureCollection(fileName);           }else{             dojo.byId('upload-status').innerHTML = '<p style="color:red">Add shapefile as .zip file</p>';          }         });          //create a popup to replace the map's info window         map = new esri.Map("mapCanvas", {           basemap: "gray",           center: [-41.647, 36.41],           zoom: 3,           slider: false         });          dojo.connect(             map             ,"onUpdateEnd"             ,this             ,function(){                 alert("is this happening?");             }         );       }        function generateFeatureCollection(fileName) {         var name = fileName.split(".");         //Chrome and IE add c:\fakepath to the value - we need to remove it         //See this link for more info: http://davidwalsh.name/fakepath         name = name[0].replace("c:\\fakepath\\","");          dojo.byId('upload-status').innerHTML = '<b>Loading </b>' + name;          //Define the input params for generate see the rest doc for details         //http://www.arcgis.com/apidocs/rest/index.html?generate.html         var params = {           'name': name,           'targetSR': map.spatialReference,           'maxRecordCount': 1000,           'enforceInputFileSizeLimit': true,           'enforceOutputJsonSizeLimit': true         };          //generalize features for display Here we generalize at 1:40,000 which is approx 10 meters         //This should work well when using web mercator.         var extent = esri.geometry.getExtentForScale(map,40000);         var resolution = extent.getWidth() / map.width;         params.generalize = true;         params.maxAllowableOffset = resolution;         params.reducePrecision = true;         params.numberOfDigitsAfterDecimal = 0;          var myContent = {           'filetype': 'shapefile',           'publishParameters': dojo.toJson(params),           'f': 'json',           'callback.html': 'textarea'         };          //use the rest generate operation to generate a feature collection from the zipped shapefile         esri.request({           url: portalUrl + '/sharing/rest/content/features/generate',           content: myContent,           form: dojo.byId('uploadForm'),           handleAs: 'json',           load: dojo.hitch(this, function (response) {             if (response.error) {               errorHandler(response.error);               return;             }             dojo.byId('upload-status').innerHTML = '<b>Loaded: </b>' + response.featureCollection.layers[0].layerDefinition.name;             addShapefileToMap(response.featureCollection);           }),           error: dojo.hitch(this, errorHandler)         });       }        function errorHandler(error) {         dojo.byId('upload-status').innerHTML = "<p style='color:red'>" + error.message + "</p>";       }        function addShapefileToMap(featureCollection) {         //add the shapefile to the map and zoom to the feature collection extent         //If you want to persist the feature collection when you reload browser you could store the collection in         //local storage by serializing the layer using featureLayer.toJson()  see the 'Feature Collection in Local Storage' sample         //for an example of how to work with local storage.         var fullExtent;         var layers = [];          dojo.forEach(featureCollection.layers, function (layer) {           var infoTemplate = new esri.InfoTemplate("Details", "${*}");           var layer = new esri.layers.FeatureLayer(layer, {             infoTemplate: infoTemplate           });           //associate the feature with the popup on click to enable highlight and zoomto           dojo.connect(layer,'onClick',function(evt){             map.infoWindow.setFeatures([evt.graphic]);           });           //change default symbol if desired. Comment this out and the layer will draw with the default symbology           changeRenderer(layer);           fullExtent = fullExtent ? fullExtent.union(layer.fullExtent) : layer.fullExtent;           layers.push(layer);         });         map.addLayers(layers);         //map.setExtent(fullExtent.expand(1.25), true);          dojo.byId('upload-status').innerHTML = "";       }        function changeRenderer(layer) {         //change the default symbol for the feature collection for polygons and points         var symbol = null;         switch (layer.geometryType) {         case 'esriGeometryPoint':           symbol = new esri.symbol.PictureMarkerSymbol({             'angle':0,             'xoffset':0,             'yoffset':0,             'type':'esriPMS',             'url':'http://static.arcgis.com/images/Symbols/Shapes/BluePin1LargeB.png',             'contentType':'image/png',             'width':20,             'height':20           });           break;         case 'esriGeometryPolygon':           symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([112, 112, 112]), 1), new dojo.Color([136, 136, 136, 0.25]));           break;         }         if (symbol) {           layer.setRenderer(new esri.renderer.SimpleRenderer(symbol));         }       }     </script>   </head>    <body class="claro">     <div id="mainWindow" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">       <div data-dojo-type="dijit.layout.ContentPane" id="rightPane" data-dojo-props="region:'right'">         <div style='padding-left:4px;'>           <p>             Add a zipped shapefile to the map.</p><p>Visit the             <a target='_blank' href="http://help.arcgis.com/en/arcgisonline/help/#/About_shapefiles/010q000000m2000000"/>About Shapefiles</a> help topic for information and limitations.</p>               <form enctype="multipart/form-data" method="post" id="uploadForm">               <div class="field">                   <label class="file-upload">                       <span><strong>Add File</strong></span>                       <input type="file" name="file" id="inFile" />                   </label>               </div>               </form>               <span class="file-upload-status" style="opacity:1;" id="upload-status"></span>               <div id="fileInfo"> </div>         </div>     </div>     <div id="mapCanvas" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>   </div> </body> </html>


If you load the above page and "Add File" appropriately, the features are added to the map, but the alert box does not appear. I expected to see it as the documentation for this event says "Fires after layers that are updating their content have completed." Can anyone provide information regarding why the event is not firing in this scenario? I thought it might be related to the fact that the layer in question is a feature layer, but find that if I add a FeatureService to my map instead, the event is triggered...so that's not it.

Any information in this respect is welcome. Alternatively, if there is some other way of knowing when the shapefile's addition to the map is complete, I'd be happy to learn it.

Cheers,
jtm
0 Kudos
1 Solution

Accepted Solutions
JoanneMcGraw
Frequent Contributor
As there was no response to my query through the forums, I contacted ESRI support. They responded with the following:

The bug for this incident was created and here are the details of it.
[#NIM090900  "onUpdateEnd" event  on Map object fails to trigger when a layer is added from the featureCollection returned through the upload of a shapefile ]


In our particular case, we have implemented a workaround until such time as this defect is addressed. We have shifted some functionality into an "onLayerAddResult" event handler to update the legend. This is not optimal, as it means the legend gets refreshed for each layer added, rather than at the end of all layers added (whether we're importing a shapefile or not), but it does the trick for now.

View solution in original post

0 Kudos
1 Reply
JoanneMcGraw
Frequent Contributor
As there was no response to my query through the forums, I contacted ESRI support. They responded with the following:

The bug for this incident was created and here are the details of it.
[#NIM090900  "onUpdateEnd" event  on Map object fails to trigger when a layer is added from the featureCollection returned through the upload of a shapefile ]


In our particular case, we have implemented a workaround until such time as this defect is addressed. We have shifted some functionality into an "onLayerAddResult" event handler to update the legend. This is not optimal, as it means the legend gets refreshed for each layer added, rather than at the end of all layers added (whether we're importing a shapefile or not), but it does the trick for now.
0 Kudos