{knowhow} Invoking an action from with EntityCollection Input parameter using WebApi in Dynamics 365

Xrm.WebApi methods introduced by Microsoft are great! But not much can be said about Xrm.WebApi.execute method which is used to invoke custom actions from client side code.

To be honest, ever since I have written blogs on Xrm.WebApi.execute like this one- https://debajmecrm.com/2018/07/20/calling-bound-actions-entity-actions-using-xrm-webapi-execute-in-dynamics-v9/, I have been getting huge number of questions on how this topic.

And one of the question that is coming time and again is – How do I pass an input parameter of type EntityCollection. I was baffled a bit as to why this question has popped up time and again but when I really go and search the docs and community, I really find very little information on the same and this answers my curiosity. Well, I have decided to pen this down. Actually it’s pretty simple but in case you don’t know, it can cost you days.

So I created an Action with two input parameters – one with Type entity reference and the other of type Entity Collection. Screenshot for reference.

image

The entity reference is of type Account as well. And in the entity collection also we are going to pass a collection of accounts.

So here is the call to the action which would work just fine.

var request = {};
request.entity = { entityType: "account", id: "475B158C-541C-E511-80D3-3863BB347BA8" };
request.EntRef = { "@account.id": "475B158C-541C-E511-80D3-3863BB347BA7" };
request.EntColl = [
    {
        "@account.id": "475B158C-541C-E511-80D3-3863BB347BA6", "name": "acc1", "@odata.type": "Microsoft.Dynamics.CRM.account"
    }
    ,
    {
        "@account.id": "475B158C-541C-E511-80D3-3863BB347BA5", "name": "acc2", "@odata.type": "Microsoft.Dynamics.CRM.account"
    }

];
request.getMetadata = function () {
    return {
        boundParameter: "entity",
        operationType: 0,
        operationName: "new_ActionProcess",
        parameterTypes: {
            "entity": { typeName: "mscrm.account", structuralProperty: 5 },
            "EntRef": {
                typeName: "mscrm.account",
                 structuralProperty: 5
            },

            "EntColl": {
                typeName: "Collection(mscrm.crmbaseentity)",
                structuralProperty: 4
            }

        }
     };
};

Xrm.WebApi.execute(request).then(
    function (result) {
        debugger;
    },
    function (error) {
    }
);

Highlighted the entity collection areas for easy readability.So as you can see, you need to pass the typeName as “Collection(mscrm.baseentity)”.

This is what we need to do. But the question is how did I find that I need to put this as the type name. After all this name is not something which can come out of intuition.

My suggestion here is, whenever you get stuck with names, fallback to the metadata.

I go to Settings –> Customizations – Developer Resources and download the OData Metadata. Once downloaded when I search for the action name this is what I find.

image

After that it’s just piece of cake.

Hope this helps and saves you some precious time.

-Debajit Dutta

(Dynamics MVP)

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

Advertisements

{knowhow} Sequencing Xrm.WebApi methods in Dynamics 365 leveraging JavaScript promise.

Come version 9.0 of Dynamics, Microsoft have introduced the Xrm.WebApi methods which have significantly eased out the task of making web api calls from the client side. However as we are all using this wonderful feature, many of us are unaware of the fact that these API’s are based on Javascript promises.

This article is not to explain what is JavaScript promise. Sharing this wonderful link in case you are unaware – http://www.javascriptkit.com/javatutors/javascriptpromises.shtml.

A great article to get started indeed.

OK. So let’s assume you are already aware of JavaScript promises. Let’s take a sample method to retrieve a record. Below is the Microsoft documentation for retrieving a record.

Xrm.WebApi.retrieveRecord(entityLogicalName, id, options).then(successCallback, errorCallback);

Concentrating on the highlighted part, the first question is – Is it absolutely necessary to define the then part of the API syntax? Can we just call Xrm.WebApi.retrieveRecord(entLogicalName, id, options) without the then part of it?

The answer is – It’s perfectly alright to call. the successCallback and errorCallback are just the event handlers when the promise is fulfilled or rejected.

Now the next part comes is – If it uses javascript promise, then it must allow sequencing. Surprisingly I have seen many implementations of Xrm.WebApi so far but I don’t see much of chaining example. Well, it can be done.

Let’s understand a scenario here. We perform a retrieve on accounts based on some query and then use the accounts to create a contact and set the parentcustomerid field to each accounts retrieved during the retrieve multiple call.

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$filter=accountcategorycode eq null").then(
    function success(result) {
         var ids = [];
        for (var i = 0; i < result.entities.length; i++) {
            var ent = result.entities[i];
             var accountId = ent.accountid;
            ids.push(accountId);
        }

        // pass the id’s to the next sequence
        return ids;
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
).
then(function (ids) {
    for (var x = 0; x < ids.length; x++) {
        var contact = {};
        contact["firstname"] = "sample";
        contact["lastname"] = "contact" + (x + 1);
        contact["parentcustomerid@odata.bind"] = "/contacts(" + ids[x] + ")";

        Xrm.WebApi.createRecord("contact", contact);
    }
});

Just focus on the highlighted part in green. As you can see here, in the successCallback of the retrieveMultiple, we first create an array of account id’s and then use the next sequence highlighted in yellow to process the Id’s and create a contact for each account retrieved. Also observe the createRecord call without the then part of it.

In this way you can chain methods as much as you want. Much better way to write than the nested callbacks.  

Hope this helps!

Debajit Dutta
(Dynamics MVP)
For consultation/ training visit
http://www.xrmforyou.com or reach out to us at info@xrmforyou.com

{knowhow} How to edit the Dynamics 365 App for Outlook screen

Recently there was a requirement to change the Dynamics 365 App for Outlook  screen. Basically when you set up the default App for Outlook, the Sitemap contains just the Activities and the Dashboards.

image

However the customer wanted to show the Accounts and some other custom entities there as well in the menu. So how do we include it?

It’s quite obvious that the change needs to be in the SiteMap. However how can I change the Sitemap of the App for Outlook screen? Strangely enough that’s one unexplored area and surprisingly even consultants working day in day out on CRM tends to miss out on this.

To modify the app UI, perform the below steps.

Open up your solution that you are working on and go to Model driven apps.

image

Add the Dynamics 365 App for Outlook app from the list of Apps.

image

Now it’s just like modifying any other app. I just quick edit the sitemap to include the account and then publish it.

Re-open the outlook and you could see your changes in there.

image

Easy wasn’t it?

Hope this helps.

Debajit Dutta
(Dynamics MVP)
For consultation/ training visit
http://www.xrmforyou.com or reach out to us at info@xrmforyou.com

Create and expose portal content easily in Dynamics 365 Portals using Portal Management feature

The true potential of a portal is realized only when we expose the Dynamics 365 content on the portals. However as we all know, to expose the content end-end, we need to create the following

  • Entity List
  • Entity Form
  • Web  Page for exposing both the entity list and the entity form
  • Separate entity forms for create and update.

Well things like this are really easy for anybody who are hands on in the portal development. However they take some time to spin up. And specially when you have some entities to set-up in one go.

Well no more worries. The new version of portals comes with the Portal Management editor that helps you do all these within minutes.

Open your CRM and go to Portals –> Administration –> Portal Management

image

Next click on “Create Portal Content”. Page like the one below would pop-up initially.

image

Make the “Display organization entity in the portal” to Yes.

image

The rest is very simple. You get to select as many views as you want just like you get when you configure an entity list. In the below screenshot i have put “Allow Record Creation” to Yes as well.

image

That’s all. Now all we need to do is expose the “cases” page in the navigation.And then you see something like this.

image

As you can see, the Create button is there and the Case title is clickable so that it redirects you to the case detail form.

Hope this helps!

Debajit Dutta
(Dynamics MVP)
For consultation/ training visit
http://www.xrmforyou.com or reach out to us at info@xrmforyou.com