Calling an Dynamics 365 Action from JavaScript

1 Comment

In this post we will call an action from JavaScript.

In a previous post, we created an action that takes 2 email inputs, a “from email” and a “to email”. When a case is created, if the case contains the word “bug”, an email is sent from the from email, and sent to the to email. The case is then assigned to the user of the “to email”.

Let’s now call this action from JavaScript. We will call this from the OnSave event of a case.

Go to the OnSave properties and click Add:

Click New:

Name the JS and click on Text Editor:

Now the code. We will need the Ids of the two users. We can look these up with a Retrieve and pass them to the action, but instead we will hardcode them and pass them. As we are using an entity reference, we will need to find the primary key name by going to the entity:

Now the JavaScript:

function RunAction() {

    var Id = Xrm.Page.data.entity.getId().replace('{', '').replace('}', '');
    var serverURL = Xrm.Page.context.getClientUrl();
    var fromUser = {};
    fromUser.systemuserid = "9C9CA531-E021-E911-A9BC-000D3A1B913D";
    var toUser = {};
    toUser.systemuserid = "6E8B062B-E021-E911-A9BC-000D3A1B913D";

    var data = {
        "FromEmail": fromUser,
        "ToEmail": toUser
    };

    var query = "incidents(" + Id + ")/Microsoft.Dynamics.CRM.new_RouteBugtoDeveloper";
    var req = new XMLHttpRequest();
    req.open("POST", serverURL + "/api/data/v9.1/" + query, true);
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.onreadystatechange = function () {
        if (this.readyState == 4 /* complete */) {
            req.onreadystatechange = null;
            if (req.status >= 200 && req.status <= 300) {
                var data = JSON.parse(this.response);
            } else {
                var error = JSON.parse(this.response).error;
            }
        }
    };
    req.send(window.JSON.stringify(data));
}

In the code, we are creating objects for the to and from users, as these are entityreferences in our process:

We then pass the Id of the case we would like the action to run on, and add “Microsoft.Dynamics.CRM” to the action name new_RouteBugtoDeveloper before passing it to the API.

On success, there will be nothing returned in the data variable.

Possible errors

“Resource not found for the segment” – this can happen if the action name is not found, for example, if new_RouteBugtoDeveloper is misspelled. Confirm the spelling and case.

“An error occurred while validating input parameters: Microsoft.OData.ODataException: One or more parameters of the operation ‘new_RouteBugtoDeveloper’ are missing from the request payload. The missing parameters are: FromEmail.” This happens if for example a parameter is not provided, in this case the FromEmail parameter.

“An error occurred while validating input parameters: Microsoft.OData.ODataException: The parameter ‘FromEmail1’ in the request payload is not a valid parameter for the operation ‘new_RouteBugtoDeveloper’. In this case, an invalid parameter was provided, FromEmail1.

“An error occurred while validating input parameters: Microsoft.OData.ODataException: Does not support untyped value in non-open type.” In this case, one of the input parameters does not contain the primary key for the object.

 

THANKS FOR READING. BEFORE YOU LEAVE, I NEED YOUR HELP.
 

I AM SPENDING MORE TIME THESE DAYS CREATING YOUTUBE VIDEOS TO HELP PEOPLE LEARN THE MICROSOFT POWER PLATFORM.

IF YOU WOULD LIKE TO SEE HOW I BUILD APPS, OR FIND SOMETHING USEFUL READING MY BLOG, I WOULD REALLY APPRECIATE YOU SUBSCRIBING TO MY YOUTUBE CHANNEL.

THANK YOU, AND LET'S KEEP LEARNING TOGETHER.

CARL

https://www.youtube.com/carldesouza

 

ABOUT CARL DE SOUZA

Carl de Souza is a developer and architect focusing on Microsoft Dynamics 365, Power BI, Azure, and AI.

carldesouza.comLinkedIn Twitter | YouTube

 

One Response to Calling an Dynamics 365 Action from JavaScript

  1. Bonjour je suis David Holgate, but that’s all the French i know 8^) that, and “isi!” when role is called!

    i have a javascript i want to call on the OnChange of Country on Accounts.
    i think the obvious problem is that, since i’m already connected, in CRM, and on the form… one wonders why i’m trying to make an HTTP call outside and back in, in order to get the data i need from the CountryRegion table, so i can pre-populate the StateRegion field with the appropriate values. For example, if they pick “USA” from a pull-down on the Country field, i want to select the CountryRegion (custom) table to get the valid Regions for that Country (in this case, in USA, we call’em “states”, i.e. “Les États-Unis” in French).
    so, i want to take values i selected after i entered Country (address1_country) and prepopulate the pull-down on the subsequent field, StateRegion (address1_stateprovince, i think). But, i can’t even get to the point where i’ve selected the data.
    so… if there’s a better, smarter way to get this data from within CRM (not calling out an odata request), then i’m all ears and i’ll discard what i have!!!!!
    otherwise, why am i getting a this error when i run the code, below that?

    Details:
    odataUri: https://orgc2cd5c37.crm.dynamics.com/api/data/v9.1/coureg_CountryRegions?$select=Region&$filter=Country = MEX

    actual javascript code:
    function getCountryRegion() {
    var oExistingCountry = new Array;
    var oSelectedRegions = new Array;

    oExistingCountry = Xrm.Page.getAttribute(“address1_country”).getValue();
    if (oExistingCountry != null) {
    var sEntityName = “coureg_CountryRegions”;
    var sColumns = “Region”;
    var sFilter = “Country = ” + oExistingCountry;
    var sOrderBy = “”;
    // Query the data…
    var requestResults = retrieveWebAPIData(sEntityName, sColumns, sFilter, sOrderBy);
    //loop through the results (there could be only one):
    if (requestResults != null) {
    if (requestResults.value != null && requestResults.value.length > 0) {
    for (var indRecordLoop = 0; indRecordLoop < requestResults.value.length; indRecordLoop++) {
    // array will be passed to the Region (States in USA) field for pre-population of the list
    oSelectedRegions[indRecordLoop] = requestResults.value[indRecordLoop];
    //oSelectedRegions.push(requestResults.value[indRecordLoop]);
    }
    }
    }
    }
    else {
    console.log("THIS oSelectedRegions = TOTAL FAILURE!");
    }
    }
    function retrieveWebAPIData(sEntityName, sColumns, sFilter, sOrderBy) {
    var globalContext = Xrm.Utility.getGlobalContext();
    var serverUrl = globalContext.getClientUrl();
    var ODATA_ENDPOINT = "/api/data/v9.1";
    var odataUri = serverUrl + ODATA_ENDPOINT + "/" + sEntityName + "?";
    if (sColumns) {
    odataUri += "$select=" + sColumns;
    }
    if (sFilter) {
    odataUri += "&$filter=" + sFilter;
    }
    if (sOrderBy) {
    odataUri += "&$orderby=" + sOrderBy;
    }
    var data;
    try {
    var req = new XMLHttpRequest();
    req.open("GET", encodeURI(odataUri), false);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "appliction/json; charset=utf-8");
    req.send(null);
    //data = JSON.parse(req.responseText, dateReviver);
    data = req.responseText;
    return data;
    }
    catch (ex) {
    console.log("Error: retrieveWebAPIData – Data Set = " + odataSetName + "; filter = " + sFilter + "; select = " + sColumns);
    }
    }
    //function dateReviver(key, value) {
    // if (typeof value === 'string') {
    // var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
    // if (a) {
    // return new Date(Date.UTC(+a[1], +a[2] – 1, +a[3], +a[4], +a[5], +a[6]));
    // }
    // }
    // return value;
    //}

Leave a Reply

Your email address will not be published. Required fields are marked *