Each time a user clicks on a list I add a new graphic on top of the clicked item.
However, I want to remove the last graphic that was created.
fyi, I can't do view.graphics.clear because before the user click I've created graphics that I need to keep.
This creates the graphic without problems.
function onListClickHandler(event) {
const target = event.target;
const resultId = target.getAt tribute("data-result-id");
// get the graphic corresponding to the clicked parcel
const result = resultId && graphics && graphics[parseInt(resultId,
10)];
var selectFillSymbol = {
type: "simple-fill", // autocasts as new SimpleFillSymbol()
color: [111, 0, 255, 0.3],
outline: { // autocasts as new SimpleLineSymbol()
color: [0,0,0],
width: 2
}
};
var polygonGraphic = new Graphic({
geometry: result.geometry,
symbol: selectFillSymbol,
attributes: simpleFillAttributes
});
view.graphics.add(polygonGraphic);
But none of these ideas below remove the graphic
capturing the reference of the last object
var lastResult = result
view.graphics.remove(lastResult);
view.graphics.remove(graphics[parseInt(lastResultId,10)];
I tried adding an attribute to the new object
since result.attributes.OBJECTID works and gives back the objectid of the original clicked item.
var simpleFillAttributes = {
Name: "newgraphic-" + result.attributes.OBJECTID
};
var polygonGraphic = new Graphic({
geometry: result.geometry,
symbol: selectFillSymbol,
attributes: simpleFillAttributes
});
and then looping through all the graphics but this give me "cannot read property Name of null"
view.graphics.forEach(function (graphic) {
if (graphic.attributes["Name"] == "newgraphic-" + result.attributes.OBJECTID) {
graphic.remove(graphic);
}
});
How can I remove the last graphic created?
Solved! Go to Solution.
Got it working with view.graphics.some not view.graphics.graphics
The main original issue was cannot read property Name of null
and this happened because I had created some graphic objects before the user did any clicking and those objects did not contain the custom attribute of Name but my new objects did have the Name attribute.
once I added the Name attribute to all the objects the code below works fine
view.graphics.some(function (graphic) {
if (graphic.attributes["Name"] == "selected-" + lastObjectID) {
view.graphics.remove(graphic);
return true;
}
});
Your idea of looping through the graphics and looking for an specific attribute is definitely the way to go but your code is wrong.
view.graphics.graphics.some(function (graphic) {
if (graphic.attributes["Name"] == "newgraphic-" + result.attributes.OBJECTID) {
graphic.remove(graphic);
return true;
}
});
View.graphics is a GraphicsLayer object not the graphics inside that layer thus you need view.graphics.graphics
thanks for your help. I'm still having problems.
when I do view.graphics.graphics.some I get "cannot read property 'some' of undefined"
so it never does the loop
when I do view.graphics.some it goes into the loop but then I get "cannot read property Name of null"
fyi, I create the graphics fine doing view.graphics.add(polygonGraphic) not view.graphics.graphics.add
Sorry I was confusing 3.x and 4.x properties.
In 4.x the view.graphics is a collection. in 3.x the map.graphics is a GraphicsLayer.
So the likely issue that the view is not initialized when you are trying to loop through it's graphics then.
view.graphics.some(function(graphic, i){
if(graphic.attributes.Name == "newgraphic-" + result.attributes.OBJECTID) {
view.graphics.remove(graphic);
return true;
}
});
Have you tried to console.log(view.graphics)?
got it. thanks! btw, what is the main difference between looping with some vs forEach?
From the dojo documentation:
some()
semantically answers the question “does a test hold true for at least one item in the array?” Like forEach(),some()
iterates over the items in an array. However, it short circuits and returnstrue
as soon as it encounters an item for which the provided callback returns a truthy value. If the callback doesn’t returntrue
for any item,some()
returnsfalse
.Note: Because of the short circuiting,
some()
can be more efficient thanforEach()
when the loop is used for comparison purposes.
Got it working with view.graphics.some not view.graphics.graphics
The main original issue was cannot read property Name of null
and this happened because I had created some graphic objects before the user did any clicking and those objects did not contain the custom attribute of Name but my new objects did have the Name attribute.
once I added the Name attribute to all the objects the code below works fine
view.graphics.some(function (graphic) {
if (graphic.attributes["Name"] == "selected-" + lastObjectID) {
view.graphics.remove(graphic);
return true;
}
});
Greetings,
I am trying to run this same type of operation to remove the last added graphic to the map but my code isn't working. Would you mind pointing me in the right direction for correcting it?
$("#btnRemovepoint").click(function () {
// alert("there were " + obsPoints.length + " points.");
clearPointForm();
obsPoints.pop();
view.graphics.some(function (graphic) {
if (graphic.attributes["Name"] == "selected-" + lastObjectID) {
view.graphics.remove(graphic);
return true;
}
});
// todo remove last point graphic
// todo remove last point from input table
});