How to refresh map after calling GraphicsLayer.remove()?

5933
6
Jump to solution
08-13-2012 08:22 AM
ShawnHolyoak
Occasional Contributor
I want to allow users to select and unselect parcels in my map.  The select works great, becauseGraphicsLayer.add() calls a "refresh" method of some sort that draws my graphics layer when invoked.  Unfortunately, when I call GraphicsLayer.remove(), that "refresh" method isn't invoked, and my graphics layer in the map is not updated, showing the graphic as still selected.  How do I remove a graphic from a GraphicsLayer and have the map update?  I'm on version 2.8 of the api.  Thanks.
0 Kudos
1 Solution

Accepted Solutions
derekswingley1
Frequent Contributor
Taking a closer look at this, graphic is a reference to a feature returned from a query task, meaning that it isn't actually in your graphics layer yet. You need to find the graphic in selectedGraphics.graphics with a particular ACCT value and pass that to selectedGraphics.remove(). I would use dojo.filter or maybe dojo.some with selectedGraphics.graphics to do this.

View solution in original post

0 Kudos
6 Replies
derekswingley1
Frequent Contributor
Can you post some code to reproduce what you're seeing? I'm guessing the argument you're passing to GraphicsLayer.remove() isn't a graphic.

Here's a simple page that shows using GraphicsLayer.remove():  http://jsfiddle.net/RsbD2/
0 Kudos
ShawnHolyoak
Occasional Contributor
Can you post some code to reproduce what you're seeing? I'm guessing the argument you're passing to GraphicsLayer.remove() isn't a graphic.

Here's a simple page that shows using GraphicsLayer.remove():  http://jsfiddle.net/RsbD2/


I'm not sure how it wouldn't be a graphic, or if it's not, it's the same object being passed to the add method as the remove method.  My method is shown below.


function showSelection(featureSet) {
 //remove all the selectedGraphics from the map, unless the CTRL key is pressed, leaving any drawnGraphics on the map
 if (!selectEvent.ctrlKey) {
  selectedGraphics.clear();
  accounts = [];
 }
 
 //QueryTask returns a feature set.  Loop through the featureset and add them to the map
 dojo.forEach(featureSet.features, function(feature){
  var graphic = feature;
  
  //add the feature if it is not already in the collection
  if (accounts.indexOf(feature.attributes.ACCT) == -1) {
   accounts.push(feature.attributes.ACCT);
   graphic.setSymbol(symbol);
   
   //add the graphic to the selectedGraphics layer
   selectedGraphics.add(graphic);
  } else {
   accounts.splice(accounts.indexOf(feature.attributes.ACCT),1);
   selectedGraphics.remove(graphic);
  }
 });
}
0 Kudos
derekswingley1
Frequent Contributor
Are you sure you're getting to selectGraphics.remove()? Try putting a console.log("removed graphic"); after selectGraphics.remove(). I ask because I think you're using array.splice incorrectly. Check out the MDN doc for more info:  https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice
0 Kudos
ShawnHolyoak
Occasional Contributor
Are you sure you're getting to selectGraphics.remove()? Try putting a console.log("removed graphic"); after selectGraphics.remove(). I ask because I think you're using array.splice incorrectly. Check out the MDN doc for more info:  https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/splice


Not sure what I was thinking on that, but that wasn't the problem.  I've updated my code to splice correctly, confirmed that the splice does work correctly (my accounts array has the proper objects in it after the splice), and I've confirmed I do get to selectedGraphics.remove(graphic), and continue without any errors.  The map does not update.  I've updated my code to show the corrected splice method.
0 Kudos
derekswingley1
Frequent Contributor
Taking a closer look at this, graphic is a reference to a feature returned from a query task, meaning that it isn't actually in your graphics layer yet. You need to find the graphic in selectedGraphics.graphics with a particular ACCT value and pass that to selectedGraphics.remove(). I would use dojo.filter or maybe dojo.some with selectedGraphics.graphics to do this.
0 Kudos
ShawnHolyoak
Occasional Contributor
Taking a closer look at this, graphic is a reference to a feature returned from a query task, meaning that it isn't actually in your graphics layer yet. You need to find the graphic in selectedGraphics.graphics with a particular ACCT value and pass that to selectedGraphics.remove(). I would use dojo.filter or maybe dojo.some with selectedGraphics.graphics to do this.

That indeed was the problem.  Once I referenced the actual graphic in the GraphicsLayer, things work properly.  Final code below.  Thanks!

function showSelection(featureSet) {
 //remove all the selectedGraphics from the map, unless the CTRL key is pressed, leaving any drawnGraphics on the map
 if (!selectEvent.ctrlKey) {
  selectedGraphics.clear();
  accounts = [];
 }
 
 //QueryTask returns a feature set.  Loop through the featureset and add them to the map
 dojo.forEach(featureSet.features, function(feature){
  var graphic = feature;
  
  //add the feature if it is not already in the collection
  if (accounts.indexOf(feature.attributes.ACCT) == -1) {
   accounts.push(feature.attributes.ACCT);
   graphic.setSymbol(symbol);
   
   //add the graphic to the selectedGraphics layer
   selectedGraphics.add(graphic);
  } else {
   accounts.splice(accounts.indexOf(feature.attributes.ACCT),1);
   
   //get the graphic that matches the feature
   var filteredGraphics = dojo.filter(selectedGraphics.graphics, function(item) {
    return item.attributes.ACCT == feature.attributes.ACCT;
   })
   graphic = filteredGraphics[0];
   selectedGraphics.remove(graphic);
  }
 });
}
0 Kudos