Add feature with attachment in single step

214
5
Jump to solution
2 weeks ago
KamilNovák
New Contributor III

Hello,

is there a way in ArcGIS Maps SDK for JavaScript how to add new feature with attachments to FeatureService in single step (using only one HTTP request in the background).

Currently, I'm able to do it by using the applyEdits() method, which adds the new feature, then I make a query based on the globalid of this new feature and use the addAttachment() method to join attachments.

applyEdits() method has a parameter addAttachments in the API documentation, too. Howewer, I think that I still need to know the globalid in that case.

Ideally, I would only need to make one request for some reasons.

Thank for replies.

 

0 Kudos
1 Solution

Accepted Solutions
UndralBatsukh
Esri Regular Contributor

Hi there, 

Yes it can be done. You need to create a new feature with a globalId and use that globalId for the attachments all in one applyEdits method. You applyEdits param would look something like the following

 

const edits = {
  addFeatures: new Collection(addFeatures),
  deleteFeatures: deleteFeatures,

  addAttachments: addAttachments,
  updateAttachments: updateAttachments,
  deleteAttachments: deleteAttachments
}

 

 

where where the new Feature has a new global id attribute set... something like GlobalID: "f0e2d7a2-b1b7-4f34-a080-c87286001e39"

Then your addAttachments array has a new attachment as created something like below:

 

addAttachments.push({
  feature: newFeature,
  attachment: {
    globalId: f0e2d7a2-b1b7-4f34-a080-c87286001e39,
    name: "your attachment name,
    data: input.files[0] || blob
  }
});

 

 

Notice that the globalId of the attachment matches the global id of the new feature you are creating. Then just call applyEdits with those two params set on `edits` param. Hope this makes sense. 

View solution in original post

5 Replies
UndralBatsukh
Esri Regular Contributor

Hi there, 

Yes it can be done. You need to create a new feature with a globalId and use that globalId for the attachments all in one applyEdits method. You applyEdits param would look something like the following

 

const edits = {
  addFeatures: new Collection(addFeatures),
  deleteFeatures: deleteFeatures,

  addAttachments: addAttachments,
  updateAttachments: updateAttachments,
  deleteAttachments: deleteAttachments
}

 

 

where where the new Feature has a new global id attribute set... something like GlobalID: "f0e2d7a2-b1b7-4f34-a080-c87286001e39"

Then your addAttachments array has a new attachment as created something like below:

 

addAttachments.push({
  feature: newFeature,
  attachment: {
    globalId: f0e2d7a2-b1b7-4f34-a080-c87286001e39,
    name: "your attachment name,
    data: input.files[0] || blob
  }
});

 

 

Notice that the globalId of the attachment matches the global id of the new feature you are creating. Then just call applyEdits with those two params set on `edits` param. Hope this makes sense. 

KamilNovák
New Contributor III

Hi @UndralBatsukh,

Thank you for your reply. I understand how to create applyEdits with parameters, as you described.

However, I’m a bit confused about where to obtain the globalid when creating a new feature on the client side. I believe that the globalid is assigned in the geodatabase. Can I use my own globalid? If so, how can I ensure that it will be unique in the geodatabase?

0 Kudos
UndralBatsukh
Esri Regular Contributor

Yes you create the globalId yourself. You could use one of the guid generators.

KamilNovák
New Contributor III

@UndralBatsukh  thank you for this information. I didn't know this strategy.

0 Kudos
KamilNovák
New Contributor III

Hi @UndralBatsukh,

can I have another question about this problem. I have finished my applyEdits() method. Its logic aligns with the following:

 

featureForSend.setAttribute("globalid", "{3b0931f2-78f6-4799-ae0f-13d26c787775}");
EditLayer.applyEdits({
  addFeatures: [featureForSend], 
  addAttachments: [{
     feature: featureForSend,
     attachment: {
        globalId: "{b99a53f2-3b76-4024-97d2-8ceca8b624ae}",
        data: input.files[0]
     }
   }]
}, {gdbVersion: "", 
    returnEditMoment: false, 
    globalIdUsed: true, 
    rollbackOnFailureEnabled: false
}).then((result) => {...

 

 This code fires HTTP request with this data:

 

Adds:
[{"geometry":{"spatialReference":{"latestWkid":5514,"wkid":102067},"x":-8988283.904533692,"y":4133042.200104993},"attributes":{"poznamka": "test", "globalid":"{3b0931f2-78f6-4799-ae0f-13d26c787775}"}}]

Attachments:
{"adds":[{"globalId":"{b99a53f2-3b76-4024-97d2-8ceca8b624ae}","parentGlobalId":"{3b0931f2-78f6-4799-ae0f-13d26c787775}","contentType":"image/png","name":"Image 001.png","uploadId":null,"data":"loremipsum"}],"updates":[],"deletes":[]}

 

... and it ends with server error "Unable to complete operation. Unable to perform applyEdits operation. An error occurred."

I’ve discovered an issue related to the "uploadId":null parameter (in Attachments data). When I remove this parametr and re-run this request again (directly in REST API), the request succeeds

However I'm not able to achieve the same result using the ArcGIS Maps SDK fo JavaScript. JS API always adds this "uploadId":null param to the HTTP request.

Is there a solution for this?  We have federated Enterprise 10.9.1 and JS API 4.27.

Thanks

 

0 Kudos