Async onSave preventDefault with external call
One of our current projects is the migration of an onPrem Dynamics 365 to the Cloud. Part of that is refactoring existing JavaScript implementation. The current implementation had an onSave function which prevented the save process based on a call to the WebAPI. It took me some time to migrate the function, therefore I thought it might be interesting for others to know how to write an async onSave preventDefault with external call.
Background
All calls to the WebAPI (through Xrm.WebApi) are done async in the Power Platform. This means if you need to get additional data to determine whether you would like to cancel the current save event you would need an async onSave.
I tried the usual approach of calling “preventDefault“, which has not given the expected result as the save was executed either way. According to the Microsoft documentation this you should in that case use preventDefaultOnError instead of preventDefault.
Cancels the save operation if the event handler has a script error, returns a rejected promise for an async event handler or the operation times out.
MS Learn
This means the preventDefaultOnError function expects a promise which should either result in success or being rejected. Doing an “await” on the call to the Xrm.WebApi will not cancel the save event.
Implementation
Let’s take a look at the implementation. Here is a simple onSave function which prevents save when there is no account with the name “Benedikt”(both in TypeScript and JavaScript).
async function onSave(eventContext: Xrm.Events.EventContext): Promise<void> { (eventContext as Xrm.Events.SaveEventContext).getEventArgs().preventDefaultOnError(); return new Promise((resolve, reject) => { Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$filter=name eq 'Benedikt'") .then( function success(result) { if (result.entities.length > 0) { resolve(); } else { reject(); } return; }, function (error) { console.log(error.message); reject(error.message); }, ) .catch((error) => { console.log(error.message); reject(error.message); }); }); }
async function onSave(eventContext) { eventContext.getEventArgs().preventDefaultOnError(); return new Promise((resolve, reject) => { Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$filter=name eq 'Benedikt'").then( function success(result) { if (result.entities.length > 0) { resolve(); } else { reject(); } }, function (error) { console.log(error.message); reject(error.message); } ); }); }
First of all we do execute the preventDefaultOnError function. As I mention this function expects a promise to be rejected (or timed out) to prevent the save.
That is the reason why we return a promise where in we do our request to the WebApi (or any other service you’d like to). The promise get’s resolved when there is more than one result. In any other case (no result or error) it get’s rejected and therefore the save of the form is cancelled.
Conclusion
I hope you learned how to create an async onSave preventDefault with external call. When you understand what the function preventDefaultOnErrror expects, it is not very hard to satisfy it.
Please let me know when you have any questions or feedback.
The post Async onSave preventDefault with external call appeared first on Benedikt's Power Platform Blog.
This was originally posted here.
Comments
-
Async onSave preventDefault with external call
*This post is locked for comments