What is the best approach to access the FormContext of a form from a WebResource hosted on the form?
The docs say to access the Form Context from a html WebResource to use parent.Xrm.Page.
An HTML web resource added to a form can’t use global objects defined by the JavaScript library loaded in the form. An HTML web resource may interact with the Xrm.Page or Xrm.Utility objects within the form by using parent.Xrm.Page or parent.Xrm.Utility, but global objects defined by form scripts won’t be accessible using the parent. You should load any libraries that an HTML web resource needs within the HTML web resource so they’re not dependent on scripts loaded in the form.
But Xrm.Page is deprecated, and will be removed. When it does, my assumption is parent.Xrm.Page will fail to work at that point in time as well.
This assumption is echo'd by a closed issue posted at the end of the doc page.
An HTML web resource added to a form can’t use global objects defined by the JavaScript library loaded in But if you look at the issues on the page above, someone asks the obvious question: To prevent a gap in functionality, how will an HTML web resource included on an entity form access the form's context, when the only supported method available today is being deprecated? Can we depend on there being a supported alternative to "parent.Xrm.Page" by the time Xrm.Page is removed?
To which the reply is to use the getContentWindow, and inject it in from the onload of the form. This still isn't great because there is no guarantee that the web resource will finish loading in time to be able to accept said value. A dev even commented as such and posted their work around on the getContentWindow doc page
function form_onload(executionContext) {
const formContext = executionContext.getFormContext();
const wrControl = formContext.getControl("new_myWebResource.htm");
if (wrControl) {
wrControl.getContentWindow().then(contentWindow => {
let numberOfCalls = 0;
let interval = setInterval(() => {
if (typeof contentWindow.setClientApiContext !== "undefined") {
clearInterval(interval);
contentWindow.setClientApiContext(Xrm, formContext);
}
else
//stop interval after 1 minute
if (++numberOfCalls > 600) {
clearInterval(interval);
throw new Error("Content Window failed to initialize.");
}
}, 100);
});
}
}
Is this currently the best/recommended approach for getting this to work, or will the parent.Xrm.Page still work even when the Xrm.Page has been removed?