When the user clicks a graphic, I want to create a temporary graphic (with the same geometry) to edit in SketchViewModel.
Basically this code, using ArcGIS JavaScript API 4.10:
this.sketchViewModel = new SketchViewModel({
layer: this.tempLayer,
view: this.mapView,
updateOnGraphicClick: false,
});
this.mapView.on("click", (e) => {
this.mapView
.hitTest(e)
.then((hitTestResult: esri.HitTestResult) => {
const hitGraphics = hitTestResult.results
.filter(x => x.graphic.layer == this.graphicsLayer)
.map(x => x.graphic);
if (hitGraphics.length > 0) {
let tempGraphic = new Graphic({ geometry: hitGraphics[0].geometry.clone() });
this.tempLayer.add(tempGraphic);
this.sketchViewModel.update([tempGraphic], {
tool: "transform",
enableRotation: true,
enableScaling: false,
toggleToolOnClick: false,
});
}
});
});
However, ArcGIS gives me the following error message:
"Parameter 'graphics' contains one or more graphics missing from the supplied GraphicsLayer."
What am I doing wrong? I'm guessing this is a threading/timing issue that happens because hitTest() is asynchronous, but I'm not sure how to work around it.
Christian,
The SketchViewModel does not applyEdits to the FeatureService by itself if that is what you are concerned about. In this sample you can do validation before you allow the edit to even be committed to graphics.
The error is telling you the issue you are attempting to clone the graphic and add it to the tempLayer after the model is initialized and because this is a new graphic that the model did not create and was not there when the model was initialized it throws that error.
I tried this approach to address two problems, the first being SketchViewModel overriding the symbol of the graphic being edited. I found a way to deal with this in the update callback, but it failed when I introduced custom symbol scaling. Perhaps I could tweak the code to make it work, but I wanted to ask here first. The second thing I wanted to accomplish was to have two symbols for the polygon being edited; both its original PictureMarkerSymbol and the polygon outline, which I could accomplish by introducing an additional graphic temporarily.
I see what you're saying. Could I then re-create the SketchViewModel each time a graphic is clicked, after the temporary graphic has been added?
Could I then re-create the SketchViewModel each time a graphic is clicked, after the temporary graphic has been added?
I don't see an issue with that.
Hi there,
This is a known issue at 4.10 and it will be fixed in 4.11. The issue is in GraphicsLayer.graphics
setter... the graphic.layer
is not assigned synchronously.
At, 4.10, you can workaround the issue by setting the layer's graphics array directly or wrapping the sketchViewModel.update in setTimeOut.
graphicsLayer.graphics = [editGraphic];
Check out this sample for simple working workaround for this issue.
Hope this helps,
-Undral
This issue doesn't appear to be fixed in 4.11. I tried it and it is still giving me the same error. Also, the setTimeout() workaround doesn't work anymore either.
I have this code and it works fine in 4.10... it doesn't work in 4.11
graphicsLayer.graphics = [graphic];
setTimeout(() => {
sketchViewModel.update({
tool: 'transform',
graphics: [graphic]
});
}, 100);
Actually, I take it back, it is fixed... this is my new code in 4.11 and it works!
graphicsLayer.graphics = [graphic];
sketchViewModel.update([graphic]);
Hi there,
Can you please post a reproducible test case? I updated this test case to use the code snippet provided and it is working as expected.
Undral,
Thanks for the quick reply. I realized the call to sketchViewModel.update also changed from 4.10 to 4.11. After I changed the parameters to match the signature of the function (array of graphics first, options next), everything worked. In 4.10 you could put the graphics array inside the options object and it would work, but in 4.11 it doesn't seem to be the case (which is fine). See the brief post I added right before yours.
Thanks!
J