executionContext hits the big time!

You've seen the executionContext in the event registration dialog and you might even have used it on occasion. Well with the release of Dynamic 365 Customer Engagement Version 9, it has been elevated to be the replacement for Xrm.Page.

The document describing the replacement for Xrm.Page details it as ExecutionContext.getFormContext – due to the capitalisation of ExecutionContext it implies that this is a global object, when in fact it must be passed as a parameter to the event handler by checking 'Pass execution context as first parameter' checkbox.

Oddly - It's still unchecked by default given its importance!

So why the change?

Imagine that we want to create a client side event on the Contact entity that picks up the parent account's telephone number and populates the contact's telephone when 'Use Account Phone' is set to Yes. We add the event code to both the form field on change and the editable grid on change for the 'Use Account Phone' field.

If we were to use the 'old' Xrm.Page.getAttribute method –it would work on the form but it wouldn't work within the grid on change event handler.

This is where the executionContext shines – it can provide a consistent way of getting to the current entity context irrespective of where the event is being fired from (form or grid).

Show me the code!

The following event handler is written using typescript – but it's essentially the same in JavaScript without the type declarations.

The important bit is that the executionContext is defined an argument to the event handler and attribute values are retrieved from the context returned by it's getFormContext() method.

static onUseCompanyPhoneOnChanged(executionContext: Xrm.Page.EventContext) {
    var formContext = executionContext.getFormContext();
    const company = formContext.data.entity.attributes.get<Xrm.Page.LookupAttribute>("parentcustomerid");
    const usePhone =
        formContext.data.entity.attributes.get<Xrm.Page.BooleanAttribute>(dev1_useaccounttelephone);
    const parentcustomeridValue = company.getValue();

    // If usePhone then set the phone from the parent customer
    if (usePhone.getValue() &&
        parentcustomeridValue != null &&
        parentcustomeridValue[0].entityType === "account") {
        const accountid = parentcustomeridValue[0].id;
        Xrm.WebApi.retrieveRecord("account", accountid, "?$select=telephone1")
            .then(result => {
                formContext.data.entity.attributes.get("telephone1").setValue(result["telephone1"]);
            });
    }
}

Some Additional Notes:

  1. All the attributes that are used in the event must be in the subgrid row (parent customer attribute in this case).
  2. You can access the parent form container attributes using
    parent.Xrm.Page.getAttribute("name").getValue()

Xrm.Page still works in Version 9 but it's a good idea to start thinking about giving executionContext the attention it deserves!

Hope this helps!

Comments are closed