Making the OnLoad event handler asynchronous

Introduction

Consider a section on a form called ‘banking details’. When the form is loaded, the section should be either visible or hidden based on certain business rules. In the case where it is to be hidden, the form would initially load with the section being visible until the custom JavaScript (to hide the section) in the OnLoad event handler is executed. Note, there will always be a delay (a fraction of a second) from when the form is initially loaded and the execution of the custom JavaScript. This is because the section may not yet have been loaded when the OnLoad event handler is executed as well as the fact the the custom JavaScript is placed at the end of the execution pipeline.

This post describes a solution where the form will appear blank i.e. Figure 1 until all the form components are ready to be displayed (including the banking details section). That is, when all components on the form have been loaded and all custom logic in the OnLoad event handler has been executed

Figure 1

Asynchronous OnLoad event handler

The ‘Async onload handler’ (Figure 2) needs to be enabled. This can be achieved by going into the model driven app, selecting ‘Settings’ and then ‘Features’. Making this change generates the underlying xml (Figure 3)

Figure 2
Figure 3

The TypeScript Code

Referring to the code below, the promise waits 0.5sec for the form to complete loading. It then calls the function to set the banking details visibility. The form won’t display until the promise resolves

export class NonComplianceForm {

    public static async onLoad(executionContext: Xrm.Events.EventContext): Promise<void> {
        try {
            const formContext = executionContext.getFormContext();

            formContext.getAttribute(cpl_noncomplianceAttributes.cpl_noncompliancetypecode).addOnChange(function () {
                NonComplianceForm.onChangeNonComplianceType(executionContext);
            });

            return new Promise((resolve, reject) => {
                try {
                    setTimeout(() => {
                        NonComplianceForm.setBankingDetailsVisibility(executionContext);
                        resolve();
                    }, 500);
                } catch (error) {
                    console.error(error);
                    reject(error);
                }
            });
        } catch (e: any) {
            console.error("The following error occured in onLoad = " + e);
        }
    }

References

https://learn.microsoft.com/en-us/power-apps/developer/model-driven-apps/clientapi/reference/events/form-onload

https://debajmecrm.com/async-onsave-handlers-in-dataverse-dynamics-365-forms-to-cancel-save-operation-stop-save-till-certain-async-events-are-executed-check-this-out/