Cancel Identify Task

4510
8
12-06-2013 09:11 AM
JessicaKnight1
New Contributor III
Can anyone give me a pointer to get the Identify task to cancel once you click the map? Or at least tie a cancel to a button? Its a bit of an annoyance that the ID task still keeps working after you click on a point.
0 Kudos
8 Replies
BenFousek
Occasional Contributor III
If you're initiating identify with map onClick you can use dojo/on once.

on.once(map, 'click', function(evt) {
  //do stuff
});


To manage the event outside itself.

var clickTheMap = on(map, 'click', function(evt) {
  //remove event when fired (equivalent to on.once)
  clickTheMap.remove();
  clickTheMap = null;

  //do stuff
});

on(myCancelButton, 'click', function() {
  if(clickTheMap) {
    clickTheMap.remove();
  }
});


If you have a lot of map events consider a helper class to manage said events. Here's the relevant parts of mine. Keep in mind I just copy/pasted this as an example to illustrate to concept. Will probably take some adaptation to implement in your app.

/* map event handling */
// primarily used for map 'click' events
// however any on-style event can be added
// does not support connect events
eventAdd: function (event) {
  this.eventOns.push(event);
},
eventBegin: function () {
  this.infoWindow.hide();
  this.infoWindow.clearFeatures();
  this.setMapCursor('default');
  this.eventMouseEventsDisable();
  arrayUtils.forEach(this.eventOns, function (o) {
    o.remove();
  });
  this.eventOns = [];
  if (this.drawToolbar._geometryType != null) {
    this.drawToolbar.deactivate();
  }
  var s = esriBundle.toolbars.draw;
  s.addPoint = 'Click to add a point';
  s.freehand = 'Press down to start and let go to finish';
  s.start = 'Click to start drawing';
  s.resume = 'Click to continue drawing';
  s.complete = 'Double-click to finish';
},
eventEnd: function () {
  this.setMapCursor('default');
  this.eventMouseEventsEnable();
  this.toaster.hide();
},
eventReset: function () {
  this.eventBegin();
  this.eventEnd();
},
eventMouseEventsEnable: function () {
  arrayUtils.forEach(this.graphicsLayerIds, function (layer) {
    this.getLayer(layer).enableMouseEvents();
  }, this);
},
eventMouseEventsDisable: function () {
  arrayUtils.forEach(this.graphicsLayerIds, function (layer) {
    this.getLayer(layer).disableMouseEvents();
  }, this);
},


Used like this.

this.map.eventBegin();

this.map.setMapCursor('crosshair');

this.map.drawToolbar.activate('point');

var o = on.once(this.map.drawToolbar, 'draw-end', lang.hitch(this, function (result) {

  this.map.eventEnd();

  //do stuff
}));

this.map.eventAdd(o);
0 Kudos
JessicaKnight1
New Contributor III
Will that work with the legacy style? I'm still using that currently and not AMD. This is the code I'm using:

 //Identify task
   function initFunctionality (map){
    dojo.connect(map, "onClick", executeIdentifyTask);
  
  
  identifyTask = new esri.tasks.IdentifyTask("http://gismap.oit.ncsu.edu/arcgis/rest/services/FiberAnalytics_IMS/MapServer");
  
  identifyParams = new esri.tasks.IdentifyParameters();
  identifyParams.tolerance = 2;
  identifyParams.returnGeometry = true;
  identifyParams.layerIds = [2,3,4,5,6,7,8,9,11,18];
  identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_TOP;
  identifyParams.width = map.width;
  identifyParams.height = map.height;
  
   }
   
    //Execute Identify Task
            function executeIdentifyTask(evt){    
                identifyParams.geometry = evt.mapPoint;
                identifyParams.mapExtent = map.extent;
                
                var deferred = identifyTask.execute(identifyParams);
                
                deferred.addCallback(function(response){
                    // response is an array of identify result objects    
                    // Let's return an array of features.
                    return dojo.map(response, function(result){
                        var feature = result.feature;
                        feature.attributes.layerName = result.layerName; 


The initFunctionality function is tied to a button in my application.
0 Kudos
BenFousek
Occasional Contributor III
Sure:
var connects = [];

function reset() {
  dojo.forEach(connects, dojo.disconnect);
  connects = [];
};

//elsewhere
reset();
var mapClick = dojo.connect(map, 'onClick', function(evt) {
  dojo.disconnect(mapClick);
  
  //do stuff
});
connects.push(mapClick);


And not to push AMD on you, but it's the way to go. 😉
0 Kudos
JessicaKnight1
New Contributor III
I will definitely be switching to AMD in the fairly near future, but I'm still getting a handle on the legacy coding!

Any more pointers? I can't seem to make it work.
0 Kudos
JessicaKnight1
New Contributor III
Anyone? Still having trouble getting this to work.
0 Kudos
ReneRubalcava
Frequent Contributor
How about similar to the on.once() method,you try on.pausable().
I made a fiddle demonstrating it here.
http://jsfiddle.net/odoe/DtJcH/

Here is the js for it.
require([
    'dojo/on',
    'dojo/query',
    'esri/map',
    'esri/tasks/IdentifyTask',
    'esri/tasks/IdentifyParameters',
    'esri/layers/ArcGISDynamicMapServiceLayer',
    'dojo/domReady!'
], function (
    on, query,
    Map,
    IdentifyTask, IdentifyParameters,
    ArcGISDynamicMapServiceLayer
) {
    var map,
    layer,
    idTask,
    idParams,
    handler,
    paused = false,
    $button = query('#btnIdentify')[0];

    map = new Map('mapDiv', {
        basemap: 'streets',
        center: [-83.275, 42.573],
        zoom: 18
    });

    layer = new ArcGISDynamicMapServiceLayer('http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer', {
        opacity: 0.5
    });

    map.addLayer(layer);

    on.once(map, 'load', function () {
        // define a pausable handler
        handler = on.pausable(map, 'click', doIdentify);

        idTask = new IdentifyTask('http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer');
        idParams = new IdentifyParameters();
        idParams.tolerance = 3;
        idParams.returnGeometry = true;
        idParams.layerIds = [0, 2];
        idParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
        idParams.width = map.width;
        idParams.height = map.height;
    });

    // handle the pausable handler
    on($button, 'click', function () {
        paused = !paused;
        if (paused) {
            handler.pause();
            $button.innerHTML = 'Paused';
        } else {
            handler.resume();
            $button.innerHTML = 'Not Paused';
        }
    });

    function doIdentify(e) {
        console.debug('identify on the map');
        idParams.geometry = e.mapPoint;
        idParams.mapExtent = map.extent;
        idTask.execute(idParams).then(function () {
            alert('Identify Complete');
        }, function (err) {
            alert('Error, sorry');
        });
    }
});
0 Kudos
JessicaKnight1
New Contributor III
I need legacy code though.
0 Kudos
ReneRubalcava
Frequent Contributor
I haven't tested this, but maybe similar to below.
var mapClick,
 allowIdentify = true;

function initConnect() {
 mapClick = dojo.connect(map, 'onClick', function(evt) {
   dojo.disconnect(mapClick);
   
   //do stuff
 });
}

function disconnect() {
 dojo.disconnect(mapClick);
}

// some sort of action, like a button click
dojo.connect(dojo.byId('btnIdentify'), 'onClick', function() {
 allowIdentify = !allowIdentify;
 if (allowIdentify) {
  disconnect();
 } else {
  initConnect();
 }

});
0 Kudos