cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Frequent Visitor

How to prevent save event when validation required database call?

I have a form in my model-driven app (9.0) that has an Amount field.  When saving the form, I need to do a lookup on the database for the user's Limit amount.  If the Amount exceeds their Limit, I need to prevent the save from happening.  I'm using 

Xrm.WebApi.retrieveRecord to make the database call, which is asynchronous.  So by the time I get the value back from the DB, the save has already happened.  Any ideas on how I can accomplish this?
 
Here's my javascript code that's wired to the OnSave event:
 
function CheckUserLimit(executionContext) {
    var formContext = executionContext.getFormContext();
    var globalContext = Xrm.Utility.getGlobalContext();

    var userId = globalContext.userSettings.userId.slice(1, -1);
    var enteredAmount = formContext.getAttribute("amount").getValue();

    Xrm.WebApi.retrieveRecord("systemuser"userId"?$select=userlimit").then(
        function success(result) {
            var userLimitresult.userlimit;
            if (enteredAmount > userLimit) {
                var alertStrings = { confirmButtonLabel: "OK"text: "The amount exceeds your user limit."title: "Limit Exceeded" };
                Xrm.Navigation.openAlertDialog(alertStrings);
                // Prevent the Save
                executionContext.getEventArgs().preventDefault();
            }
        },
        function (error) {
            var alertStrings = { confirmButtonLabel: "OK"text: "Error retrieving system user limit: " + error.messagetitle: "Error Encountered" };
            Xrm.Navigation.openAlertDialog(alertStrings);
        }
    );
}
3 ACCEPTED SOLUTIONS

Accepted Solutions
MVP

Hello,

You can check my post that describes scenario that is pretty similar to yours - https://butenko.pro/2018/11/15/cancelling-save-based-on-the-result-of-async-operation/

View solution in original post

Super User
Super User

Hi @tschopp , 

 

Since the callback added with addOnSave doesn't work with promises, the only way you can go is stopping the Saving while it waits for the promise, as @a33ik 's Blog shows.

In my experience, this might cause some issues when the standard functionality is calling the formContext.data.save, since this promise will always get rejected, and the promise.then will never be executed (even if the save is restarted after the async request, the original promise gets rejected). Some examples of issues are the BusinessProcessFlows or some standard ribbon buttons.

The sdk recommends to implement the saving validation using a PlugIn, in case the data is not on the form. This doesn't work good in some cases where you have to react to it and show the user some choices, but it seems to me that in your case a PreValidate PlugIn might be a good choice.

Hope it helps.

Kind regards,

Diana
----------
Please click "Accept as Solution" if my post answered your question so that others may find it more quickly. If you found this post helpful consider giving it a "Thumbs Up."

View solution in original post

Frequent Visitor

Your ideas are good ones.  Thank you.  They led me to my solution which is to get the user limit value in the OnLoad event for the form and save it in a global JS variable.  Then, in OnSave, I can make the comparison without need to make the async retrieveRecord call.

View solution in original post

4 REPLIES 4
Advocate I
Advocate I

Both the onsave event and the retrieve call supports promises. So if you make your onsave function async and await your retrieve call you can treat the retrieve call as synchronous.

 

So the code would look like 

async function OnSave(){

....

var response = await Xrm.WebApi.retrieve(..)

...

}

 

Learn more about async await here https://javascript.info/async-await

 

Also consider using typescript instead, makes it easier to maintain the code

MVP

Hello,

You can check my post that describes scenario that is pretty similar to yours - https://butenko.pro/2018/11/15/cancelling-save-based-on-the-result-of-async-operation/

View solution in original post

Super User
Super User

Hi @tschopp , 

 

Since the callback added with addOnSave doesn't work with promises, the only way you can go is stopping the Saving while it waits for the promise, as @a33ik 's Blog shows.

In my experience, this might cause some issues when the standard functionality is calling the formContext.data.save, since this promise will always get rejected, and the promise.then will never be executed (even if the save is restarted after the async request, the original promise gets rejected). Some examples of issues are the BusinessProcessFlows or some standard ribbon buttons.

The sdk recommends to implement the saving validation using a PlugIn, in case the data is not on the form. This doesn't work good in some cases where you have to react to it and show the user some choices, but it seems to me that in your case a PreValidate PlugIn might be a good choice.

Hope it helps.

Kind regards,

Diana
----------
Please click "Accept as Solution" if my post answered your question so that others may find it more quickly. If you found this post helpful consider giving it a "Thumbs Up."

View solution in original post

Frequent Visitor

Your ideas are good ones.  Thank you.  They led me to my solution which is to get the user limit value in the OnLoad event for the form and save it in a global JS variable.  Then, in OnSave, I can make the comparison without need to make the async retrieveRecord call.

View solution in original post

Helpful resources

Announcements
News & Announcements

Community Blog

Stay up tp date on the latest blogs and activities in the community News & Announcements.

secondImage

Power Platform 2020 release wave 2 plan

Features releasing from October 2020 through March 2021

PP Bootcamp Carousel

Global Power Platform Bootcamp

Dive into the Power Platform stack with hands-on sessions and labs, virtually delivered to you by experts and community leaders.

secondImage

Power Platform Community Conference On Demand

Watch Nick Doelman's session from the 2020 Power Platform Community Conference on demand!

Users online (7,185)