This post describes how to make a Dynamics 365 form load asynchronously to avoid incorrect values being displayed on the initial load of the form
An example of the issue
Consider a section on a form called ‘banking details’ which contains a column called ‘home loan interest rate’. If this column is initially blank but populated on the onload, there is no issue. That is, when the form is initially loaded, the column is blank and only populated a fraction of a second later after the on load JavaScript has executed. However, what if the form is initially loaded with a column value of say 5% and the onload JavaScript updates the value to 5.5%. It would obviously be better if the initial value of 5% is never displayed.
Note, there will always be a delay (a fraction of a second) from when the form is initially loaded and the execution of the on load 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 custom JavaScript is placed at the end of the execution pipeline.
One possible solution to this issue described above is to hide the ‘banking details’ section and only display it (via JavaScript) once the home loan interest rate column has been updated. Another solution is described below
A solution
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 (in the background) and all custom logic in the OnLoad event handler has been executed. The only exception to this seems to be that the BPF will display before the promise is resolved
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)
The TypeScript Code
Referring to the code below, the promise waits 0.5sec for the form to complete loading (in the background before being displayed). 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);
}
}
Further reading
The following blog post has an issue which describes the client API formContext.data.refresh() List of dynamics 365 issues with a suggested next step