Editing temporary Graphic in SketchViewModel

3923
8
03-12-2019 01:38 AM
ChristianAlfons
New Contributor II

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.

0 Kudos
8 Replies
RobertScheitlin__GISP
MVP Emeritus

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.

https://developers.arcgis.com/javascript/latest/sample-code/sandbox/index.html?sample=sketch-update-... 

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.

0 Kudos
ChristianAlfons
New Contributor II

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?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

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.

0 Kudos
UndralBatsukh
Esri Regular Contributor

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

JORGETORO
New Contributor II

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);

0 Kudos
JORGETORO
New Contributor II

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]);

0 Kudos
UndralBatsukh
Esri Regular Contributor

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. 

JORGETORO
New Contributor II

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