Getting FormContext in Power Apps Custom Component framework–Gotchas!

Before I proceed further some disclaimers here. If you are thinking from the title that I have been able to resolve the problem completely, unfortunately it’s not. My approach works for certain scenarios and not for all scenarios and I will explain where it works and where it doesn’t. And this is of the time I am writing this blog. Very soon Microsoft may release something much simpler.

Ever since I wrote the article on in-depth walkthrough of Power Apps custom control, I have been flooded with questions and one of them was – “How do I get the formContext inside my custom control code so that I can interact with other attributes on the form?”. And in the series of blogs, I have used Xrm.Page construct to access some attributes on the form and as we all know, it has been deprecated. Honestly when I used Xrm.Page I used it for brevity as I  didn’t find much time to explore all the variables that the custom framework has to offer and I thought it would be easy one.

But when I went back and started searching I could not find anything the context provides to get the formContext.

I would be happy to know here that I have missed and there is a simple way to do this, I would take this blog post off and would be relieved as personally I am stuck because of this.

But if you are in the same boat as me, you can keep reading.

So here I was baffled. After-all I took it for granted and then it was not there or may be I could not find it. Searched the heck out of Google and could not find it as well.

So falls back to find it myself. I started digging and after hours of effort came up with a way to do this. May not be ingenious or best way but works for certain scenarios (doesn’t work for all. that’s the sad part.)

The first thing that struck me is that I need to keep the formContext somewhere globally so that I can see it in my control code as well. And the only way seemed logical is to do that in the onload form event.

So one part is sorted out. But how about accessing global variables in different context. After all the custom component code and the form on-load script works in different frames.

Just to illustrate, the form scripts execute in one of the frames below “top” where custom component code executes.

Form Script frame                                                           Custom component code frame

image                image

So if I can maintain a global variable holding the form context in the “top” frame, it would be available in custom component code.

I took Account Entity as an example and registered a form load event handler. Below is the script code.

if (typeof (Demo) == "undefined") {
    Demo = { __namespace: true };
}

Demo.Account = {
    _parent: parent,
    formContext: null,
    OnLoad: function (e) {
        debugger;
        this.formContext = e.getFormContext();
        this._parent.pageContext = this.formContext;
    }
};

Demo.Account.OnLoad is called on Account form load. When the function is called, it sets a variable called “pageContext” in the parent scope with the value of “formContext”. So far so good!

Here is my custom component embedded on the same account form.

image

I have registered an event handler for on click of submit button. What will I do now is try to access the formContext which is now stored a variable called “pageContext”.

When I click the submit button, the click event fires as expected.

image

If I go to console now and evaluate “pageContext” variable, it is nothing but “formContext”.

image

image

Whoooo! So everything just works fine. You can keep on using the this variable now in your control. Wasn’t it simple? Yes it was. Is it a complete solution. The answer is “NO”.

Before I go into the problem, lets go back to our basics here. If you are from the world of ASP.NET web programming and is aware of page lifecycle, you would be aware that page_init method will call control_init method of all the controls on page and then page_load will fire post page_init. The page_load method would only complete when all the controls on the page has been initialized and load completed.

If we bring this knowledge to our custom component, the init method custom component would fire before my form on-load script fires. So when the user opens up a record, the page load begins and the init method of your control fires. “Please note that by the time the init method of your control fires, the form load of the page has not been complete yet and hence the form load script won’t fire by that time.”

So what this mean? If you are trying to access the “pageContext” variable that we have used earlier you won’t find it in there. Even worse is if you are opening are moving from one record to another and try to access the pageContext inside your init method, you may end up getting the pageContext value from previous record.

So what are the other alternatives?

  • There might be simpler ways coming up in next releases or I have missed a simple way or something is already there which didn’t catch  my eye (believe me I would be happy is someone points that out).
  • Keep using Xrm.Page until MS releases a simpler like we still do for web-resources embedded in CRM form.

Hope this helps!

Debajit Dutta

(Dynamics MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Our product offerings:

Role based views for Dynamics 365 (http://www.xrmforyou.com/role-based-views.html)

CRM-Sharepoint Attachment uploader and metadata manager (http://www.xrmforyou.com/sharepoint-integrator.html)

Record Cloner for Dynamics 365 (http://www.xrmforyou.com/record-cloner.html)

Multiselect picklist for Dynamics 365 (http://www.xrmforyou.com/multi-select-picklist.html)

Advertisements

{Dynamics 365 for Sales AI} How are relationship analytics calculated? Let Microsoft Docs tell you

Recently I have been working on setting up various features of Sales AI for a customer and I have to tell you that there is so much to it than meets the eye. And one of them is the Relationship Analytics. If you go to Account/ Contact/ Lead/ Opportunity form then you would see some Relationship Analytics showing up. Below is the screenshot for an opportunity.

image

But the question is – “How is Microsoft showing up all these values? After all they must be based on some logic right?”.

Then answer is – “ Yes they are.” But believe me, if you are not aware of the logic behind it, it may be very difficult to understand. And frequently when we are distress we come home to find salvation. And so you should come back to Microsoft Docs to understand what the complexity is all about.

When I asked my colleague to refer to docs, honestly they missed out this section in the entire documentation. Hence in this article I am sharing the exact link in Docs which explain this.

And here it goes.

This link directly takes you to relationship analytics calculation logic which my otherwise be difficult to find.

Hope this helps!

Debajit Dutta

(Dynamics MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Our product offerings:

Role based views for Dynamics 365 (http://www.xrmforyou.com/role-based-views.html)

CRM-Sharepoint Attachment uploader and metadata manager (http://www.xrmforyou.com/sharepoint-integrator.html)

Record Cloner for Dynamics 365 (http://www.xrmforyou.com/record-cloner.html)

Multiselect picklist for Dynamics 365 (http://www.xrmforyou.com/multi-select-picklist.html)

What does “context” object hold in Power Apps custom component framework. Organization info, user info, web API methods and more!

After my detailed post on Power Apps Custom component framework, I have getting loads of queries and among them the common ones are

  • How do we get organization details within my Power Apps custom control
  • How to get context user information
  • How to get record information on which the control  is embedded
  • How to query Web API from my control code.

The answer to all of these lies in the context object that gets passed to the init method of your control. Just like with Plugin context, the control context contains all information about the current environment in which it is executing.

So let’s explore what the context has in store for us. And what’s better way than the wonderful developer tools of Chrome browser. Below is a screenshot of the property bag that context contains.

image

The important ones I just highlighted. So let’s go a bit granular on the highlighted one.

1. page:

context.page can help you with useful values like the id of the current app which is loaded, the guid of the record and the logical name of the record on which the control is showing up.

And also our very own lovable method – getClientUrl().

image

2. orgSettings

I think the name justifies all. This gives us all the values related to the CRM organization. And this is the same one you get when you query for Organization Settings using Xrm.Utility.getGlobalContext()

image

3. userSettings

This will give you information about the logged in user security roles, language code, user id etc.

image

4. webAPI

Well this can be very important. Specially if you want to query CRM web api from your control. Here you get all the methods to communicate with CRM Web API.

image

Hope that gives you all the information to get started with your first custom component.

Hope this helps!

Debajit Dutta

(Dynamics MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Our product offerings:

Role based views for Dynamics 365 (http://www.xrmforyou.com/role-based-views.html)

CRM-Sharepoint Attachment uploader and metadata manager (http://www.xrmforyou.com/sharepoint-integrator.html)

Record Cloner for Dynamics 365 (http://www.xrmforyou.com/record-cloner.html)

Multiselect picklist for Dynamics 365 (http://www.xrmforyou.com/multi-select-picklist.html)

Talking points in Dynamics 365 AI for Sales–Gotchas!

Introduction of Dynamics 365 AI has been a game changer in the field of Dynamics 365 and personally I have seen that mentioning this feature many a times drive the decision makers to choose Microsoft CRM over it’s competitors.

And if you are a Dynamics consultant, it’s obvious that you are have either read it or explored this feature yourself or may be just demoing this to your customer. And here I was demoing some of the features to my customer before being grilled specially with “Talking Point” feature of AI for sales.

This blog is not about configuring and setting it up but rather exploring how it works with various scenarios. Personally I find documentation related to these features in Microsoft docs not to be very detailed and your real life experiences are your best learning. Sharing some of them through this blog.

Although I will explain this feature a bit here but in case you want to learn more about this and how to configure it and get started, click here.

So what is this feature all about? Well, “Talking Points” feature is a great one for sales guys especially in scenarios where you haven’t interacted with your customers for sometime and you want to initiate a conversation. Talking Points is loosely termed as “Ice breakers” or “Conversation starters”. To put in Microsoft words – “In Dynamics 365 for Sales, Talking points provides a mechanism to automatically identify such conversation starters from your emails. The conservation starters include topics that are related to sports, vacation, family, and entertainment. These insights are available on the contact page.”

image

So let’s see the common checklists you can verify in case talking points does not give expected outcome. Please note that some are documented and some are based on my personal observations based on the way functionality works as of time I write this blog. The logic may be changed by Microsoft with time.

1. Verify Connection graph is enabled

While this is one of the step mentioned in Microsoft docs, from personal experience I have seen consultants missing this step. To enable this, login with your office admin account and enable “Connection graph” from Settings –> Services & add-ins –> Dynamics 365 AI for Sales – Connection Graph and enable it.

image

image

2. Email’s sent by you to your customer are not considered.

I believe it’s quite obvious. A sales guy may be sending lots of email to their customers and some of them may fall in the category of talking point. But that does not necessarily mean they can be conversation starters. So only the emails coming from your customer and falls in the category configured for talking points will be considered and shown in CRM UI.

3. It’s the description or email body that matters and not the subject (as per my observation)

Now this can be a confusing one. And honestly it came as surprise for me. So lets take the examples below.

Below one is the email from my customer to me updating me he saw me in football match yesterday.

image

While this email appears when I enable the auto-capture feature in Dynamics, the same does not appear in the talking points section configured although it should have shown up in sports category.

The only talking point that appears now is about family.

image

Now below is the next email in which the customer conveys the same message. But this time in the email body.

image

And now when I open the contact record and check for the talking points section, it lists out as a conversation starter with the customer in “Sports” category.

image

The reason why I put it “as per my observation” is because this is from my experience while setting this up for my customer. Didn’t find anywhere documented though. I would be happy if anyone could find me a link.

4. Talking points displayed are sensitive to the context of logged in user.

Well this one is pretty obvious. But it still gets a mention here because believe it or not, sometimes the simplest of stuffs baffles us.

Dynamics will display only the conversations that took place between CRM user and the contact. For e.g – in the talking points section, the logged in user can only see his/ her past interactions with the contact as conversation starters (provided they match the category). Not related to any role in Dynamics system.

Quite obvious right. No-one should be able to view your conversations with the customer.

5. If I have duplicate contacts with same email address, what would happen?

The answer to this is, it would show up in talking points for both the contacts as the conversation is being tracked based on email address only.

So this was my list. What’s yours? I would be happy to add it here. It’s a new area and loads of stuff to explore.

Hope this helps!

Debajit Dutta

(Dynamics MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Our product offerings:

Role based views for Dynamics 365 (http://www.xrmforyou.com/role-based-views.html)

CRM-Sharepoint Attachment uploader and metadata manager (http://www.xrmforyou.com/sharepoint-integrator.html)

Record Cloner for Dynamics 365 (http://www.xrmforyou.com/record-cloner.html)

Multiselect picklist for Dynamics 365 (http://www.xrmforyou.com/multi-select-picklist.html)

{In-depth end-end walkthrough} Develop your custom controls using Power Apps Component framework and use it on your CRM interface.

Before I stepped in the wonderful world of Dynamics, I used to develop custom controls in ASP.NET. Couple of days back when Microsoft announced the release of Power Apps component framework using which you can develop custom controls and use it on Dynamics forms, I was overwhelmed. It was kind of nostalgia for me. Going back to the old glory days of custom control development.

And here I was reading the pre-release documentation from Microsoft. https://docs.microsoft.com/en-us/powerapps/developer/component-framework/custom-controls-overview 

As I was reading I could find that while all the pieces are documented, there are certain areas in documentation where developers may get stuck. Also the documentation does not show end to end of how your custom control can end up being used on a CRM Form.

So I am penning down this blog for all my blog readers. A detailed, end-end scenario where you will develop your custom controls and use in CRM eventually.

To keep each blog short -  I have divided it into a series of blogs.

Part – I  – Understanding Custom Component Framework and control lifecycle

Part – 2 – Setting up development environment and Custom Component Project

Part – 3 – Set-up Manifest file for your custom control

Part – 4 – Develop your Power Apps Custom Control UI and events

Part – 5 – Build, Test and Deploy your Power Apps Custom Control

Part – 6 – Embed your Custom control on CRM form

Debajit Dutta

(Dynamics MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com

Our product offerings:

Role based views for Dynamics 365 (http://www.xrmforyou.com/role-based-views.html)

CRM-Sharepoint Attachment uploader and metadata manager (http://www.xrmforyou.com/sharepoint-integrator.html)

Record Cloner for Dynamics 365 (http://www.xrmforyou.com/record-cloner.html)

Multiselect picklist for Dynamics 365 (http://www.xrmforyou.com/multi-select-picklist.html)

Part 6 – Embed your Power Apps Custom control on CRM form

The article is a part of series of blog posts on Custom component framework topic. In order to get the context I would suggest to get started from beginning.

In our previous article, we learnt how to build and deploy our custom control to CRM environment. To test it, I will use the account entity.

I will create three fields first in account entity

1. File Control – Single Line of Text

2. File Size: Whole Number

3. File Name: Single Line of Text.

4. Content – Single Line of Text (Format – TextArea)

I will place them on the form. This is what my form look like post above steps.

image

I will put my control for File Control field. So I double click to edit it. And what a treat! I could see my FileControl right up there. If you remember, while defining the manifest file, I created the type-group for whole number and Single Line of text field. Since FileControl is single line of text, hence my control is showing up.

image

Again in the manifest, we have put it to bound. So you need to select the bound attribute for each property we defined in manifest file.

image

Awesome. Isn’t it? Now just save and publish.

Now finally when I see the unified interface, I could see the below

image

And when I select a file, I can see FileName and FileSize fields getting updated.

Even if you want upload a file more than 1 MB and click on Submit button, the validation fires. A treat to eyes when you see something working.

image

Hope this helps!

Debajit Dutta

(Business solutions MVP)

For consultation/ corporate training visit www.xrmforyou.com or reach out to us at info@xrmforyou.com or our training page http://www.xrmforyou.com/training-.html

Our product offerings:

Role based views for Dynamics 365 (http://www.xrmforyou.com/role-based-views.html)

CRM-Sharepoint Attachment uploader and metadata manager (http://www.xrmforyou.com/sharepoint-integrator.html)

Record Cloner for Dynamics 365 (http://www.xrmforyou.com/record-cloner.html)

Multiselect picklist for Dynamics 365 (http://www.xrmforyou.com/multi-select-picklist.html)

Part 5 – Build, Test and Deploy your Power Apps Custom Control

The article is a part of series of blog posts on Custom component framework topic. In order to get the context I would suggest to get started from beginning.

Now that we have developed our control in the previous article it’s time to build, test and deploy.

The first is to build your component. To build you need to open Visual Studio 2017 developer command prompt and navigate to folder where your code file is there (index.ts).

In my case it is c:\Debajit\Blog\PowerControls\FileControl

image

Once in the directory, run the command “npm run build”

image

As you can see, Build is successful. Now it’s time to test whether your control is rendering correctly before we deploy it to CRM.

Just type “npm start” in command line. It will launch IE process and show you. As you can see from screenshots my file control with submit button is rendered successfully. Look’s ugly but works just fine.

image

image

So build successful and tested as well. Now we need to put in CRM. But how?

The first thing we need is to create a solution file (zip archive) and bundle our custom component inside that solution. Before I do that, I create a new folder called “Deployment” inside my “PowerControls” folder and navigate to that folder from Visual studio command prompt. In my case the full path is “C:\debajit\blog\powercontrols\deplpoyment”.

I then run the below command

pac solution init --publisherName <enter your publisher name> --customizationPrefix <enter your publisher name>

Here in publisher name I put – “xrmforyoucontrols” and in customizationPrefix I put – x4uctrl. So my command line is

pac solution init --publisherName xrmforyoucontrols --customizationPrefix x4uctrl. Basically it creates a publisher with the specified customization prefix.

You will get notified in the console that deployment is successful.

image

The next step is to add our custom control reference. To do this run the below command.

pac solution add-reference --path <path or relative path of your PowerApps component framework project on disk>

Please note here that the path is till the directory where your component directory resides. My component directory is “FileControl” and is within C:\Debajit\Blog\PowerControls

image

To generate the solution zip file, the final step is to run first – “msbuild /t:restore” and then once that is completed, run “msbuild”

MSBUILD /t:restore

image

MSBUILD

image

And finally when I open my deployment folder, I could see bin folder. Navigate inside bin\debug and you would find your solution file.

image

Import the solution file into your environment and publish all customizations.

The final step is using the control in CRM which is covered in the next article.