I am working on an application designed for users to make some simple feature layer edits. The users have full add/update/delete privileges. Another portion of the application generates a string value. I would like to have this value automatically included as the value of one of the fields whenever a user makes an edit. I don't care if the user sees this value or not, but the user should not be able to change it.
In a similar application, I was able to do this using @JoelBennett's solution from this post.
editorVM.watch(['state', 'featureFormViewModel.feature', 'featureFormViewModel.state'], () => {
if (editorVM.state == 'creating-features' && editorVM.featureFormViewModel.feature && editorVM.featureFormViewModel.state == 'ready') {
window.setTimeout(function() {
editorVM.featureFormViewModel.setValue('PhoneNumber', "999.999.999")
}, 200);
}
});
But there are two complications for this application.
Feature layers have the edits event that can be watched for, but it happens after the applyEdits() method completes. If I try to use applyEdits() inside this event, I will create an infinite loop. The code I want to write would intercept before the applyEdits() method is called, inject my value into the attributes and then proceed saving the edits.
Goal: Automatically add string variable to the attributes of a Feature Layer whenever it is edited in an application.
Restrictions:
Solved! Go to Solution.
An ugly but effective way to intercept a function call prior to its execution is to store a reference to the function, override it with your custom processing, and then call the original function at the end like so:
var featureLayer = new FeatureLayer({
//etc
});
featureLayer.originalApplyEdits = featureLayer.applyEdits;
featureLayer.applyEdits = function(edits, options) {
//do whatever you want to the "edits" object
return this.originalApplyEdits.apply(this, arguments);
};
in terms of accessing the viewmodel for the widget I have found that it is seemingly possible via an undocumented property on the web components. I have implemented some additional logic to hook into some viewmodel events/properties on the Features Component.
function isWaitingForResult(element: HTMLArcgisFeaturesElement) {
return element.widget?.viewModel?.waitingForResult ?? false;
}
An ugly but effective way to intercept a function call prior to its execution is to store a reference to the function, override it with your custom processing, and then call the original function at the end like so:
var featureLayer = new FeatureLayer({
//etc
});
featureLayer.originalApplyEdits = featureLayer.applyEdits;
featureLayer.applyEdits = function(edits, options) {
//do whatever you want to the "edits" object
return this.originalApplyEdits.apply(this, arguments);
};
Thanks, @JoelBennett. It works. For the record, here's what my completed function looks like.
featureLayer.originalApplyEdits = featureLayer.applyEdits
featureLayer.applyEdits = function (edits, options) {
console.log(edits, options)
if (edits.addFeatures || edits.updateFeatures) {
const features = edits.addFeatures || edits.updateFeatures
features.forEach(feature => {
feature.attributes.attributeName = value
})
}
return this.originalApplyEdits.apply(this, arguments)
}
I don't know if the if statement is necessary, I just threw it in case.