OnSave Asynchronous event handler in Dynamics 365 model-driven apps(Very Useful)
OnSave event handler in Dynamics 365 or Data Verse is very commonly used by developers to write logics on data validations or creating related records etc. But if we write any logic inside OnSave event handler those are asynchronous then the Save operation do not wait till the operation gets completed.
To address this issue now Microsoft Dynamics 365 and Data verse supports Asynchronous OnSave events using Promises. The OnSave
event becomes async when a promise is returned by an OnSave
event handler and support is enabled. We can enable the support by updating the customization.xml
file for the app we want. The configuration model driven application specific.
So Lets us see how we can configure:
Step : 1 -Enable Async OnSave using app setting
Create a model driven app and add required components. Create a Solution and add the model driven app inside the solution. My App name is “cr8eb_AccountManagement“.
To enable the async OnSave
event handlers for a specific app, add the below XML in the customization.xml
file. This should be added in the existing AppModule node in your customization.xml
file.
Export the Solution and Extract the Solution to edit customization.xml. Edit the App Module. make sure to use the appsetting unique name. for me it is “cr8eb_AccountManagement_AsyncOnSave”.It should be your app name and hen underscore then AsyncOnSave. Also make sure to update value true.
Once you done this Re-zip the files and Re-import to environment and Publish.
Step 2 – Now we will write code for Async On save
Write the below code. In the below code I have added onSave method dynamically on contact form and inside on save event I am calling a function validateSaveAsync which checks if email address exist or if not exist we are cancelling save operation by returning Promise either resolve or reject.
function onContactFormLoad(executionContext) { var formContext = executionContext.getFormContext(); formContext.data.entity.addOnSave( (() => { return async (eContext) => { eContext.getEventArgs().preventDefaultOnError(); await validateSaveAsync(eContext); } } )()); } var validateSaveAsync = (eContext) => { return new Promise((resolve, reject) => { var recordId = eContext.getFormContext().data.entity.getId().replace("{", "").replace("}", ""); Xrm.WebApi.retrieveRecord("contact", recordId, "?$select=email") .then(function (result) { if (result.email === undefined || result.email === null) { resolve(true); } else { reject("error"); } }); }); }
I hope it helps.