Stop using OData V2.0 endpoint going further for your implementations….!

Hi Folks,

This blog is just to let you know why you should stop implementing OData calls using V2.0 version. I am pretty sure almost every Dynamics CE project out there have used this OData calls definitely in their implementations from quite some time. While some of new implementations have replaced the logic using Web API, still some people go with using OData V2.0 calls to build their functionality using JavaScript.

Microsoft had actually planned to remove this endpoint from April 30, 2023. But they deferred this because many projects are’nt yet prepared for removal of this end point and help the customers prepare for this transition to Web API end point.

Identify if you still using OData V2.0 end point, actually Organization Data Service is an OData V2.0 endpoint which was introduced with Dynamics CRM 2011..it’s deprecated way back with Dynamics 365 CE version 8.0.

So now, how to identify where and all you were using OData End Points in your code…you shouldn’t expect that existing code will work with only minor changes and this work can be taken at a later stage. This was a high priority warning message from Microsoft stating the removal, so I urge all of you to be prepared for this removal very soon and you shouldn’t be surprised.

So where to change…..?

Below are the places where you should change your way of implementation and align with Microsoft…

  1. The Organization Data Service using this end point /XRMServices/2011/OrganizationData.svc in Javascript, you can find it out with the help of the checker service rule web-avoid-crm2011-service-odata for identification. This can be code which was making OData calls to perform CRUD Operations on the current table or related table.
  2. Check any other code, including PowerShell scripts, that send requests to this endpoint: /xrmservices/2011/organizationdata.svc.
  3. Cross Check your Power BI reports or Excel Data sources that may be using this endpoint.

Note:

This announcement does not involve the deprecated Organization Service SOAP endpoint, meaning using Organization service in plugins. At this time, no date has been announced for the removal of that endpoint. At the time of writing this blog post, Microsoft didn’t announce whether this removal is only for Online or On Premise Versions.

References:

How to use Application Insights to identify usage of the OrganizationData.svc endpoint?

OData v2.0 Service removal date announcement

The Clock is Ticking on Your Endpoint

Do not use the OData v2.0 endpoint

Hope this saves time and effort implementing your Dynamics CE Solutions…

Cheers,

PMDY

Xrm.WebAPI with Promise for synchronous calls in Javascript

Hi Folks,

Here is how I have quickly achieved the synchronous Retrieve multiple call using Web API and Promises with the help of JavaScript. I don’t want to make my post too detail, but I would like to share the approach.

All I want to do is to just Restrict saving the Contact creation if the Postal Code entered is not present in the system. But this call should be synchronous as the message should be shown immediately incase postal code is not found in the system and prevent saving the contact record. All you need to do is simple, just call the below function on change of Postal Code in Contacts.

Here in place of XMLHTTPRequest, I have used Xrm.WebAPI so that it won’t show a critial warning in Solution Checker.

ValidatePostalCode: function (executionContext) {
"use strict";
var formContext = executionContext.getFormContext();
var postalcode = formContext.getAttribute(Resident.Fields.address1_postalcode).getValue();
var message = "Please enter a valid Postal code; Refer to Postal Code Mappings"
var uniqueId = "cnt_postalcodenotpresent";
return new Promise(function (resolve, reject) {
Xrm.WebApi.retrieveMultipleRecords("new_postalcodes", "?$select=new_postalcode&$filter=hsg_postalcode eq '" + postalcode + "' ").then(
function success(result) {
var isNotFound = false;
if(result !== undefined)
isNotFound = result.entities.length === 0 ? true : false;
if (isNotFound) {
var errorMessage = "Postal Code Mapping is not present for the given postal code"
formContext.ui.setFormNotification(errorMessage, "ERROR", uniqueId);
}
else {
Resident.isValidationNeeded = false;
formContext.ui.clearFormNotification(uniqueId);
formContext.data.entity.save();
}
// return true or false
resolve(isNotFound);
},
function (error) {
reject(error.message);
//console.log(error.message);
}
);
});
}

References:

What is Promise?

Web API Retrieve Multiple

Action based on Async Operation

Cheers,

PMDY

JavaScript Arrow Functions

In this tutorial, you will learn about JavaScript arrow function with the help of examples.

Arrow function is one of the features introduced in the ES6 version of JavaScript. It allows you to create functions in a cleaner way compared to regular functions. For example,

This function

// function expression
let x = function(x, y) {
   return x * y;
}

can be written as

// using arrow functions
let x = (x, y) => x * y;

using an arrow function.


Arrow Function Syntax

The syntax of the arrow function is:

let myFunction = (arg1, arg2, ...argN) => {
    statement(s)
}

Here,

  • myFunction is the name of the function
  • arg1, arg2, ...argN are the function arguments
  • statement(s) is the function body

If the body has single statement or expression, you can write arrow function as:

let myFunction = (arg1, arg2, ...argN) => expression

Example 1: Arrow Function with No Argument

If a function doesn’t take any argument, then you should use empty parentheses. For example,

let greet = () => console.log('Hello');
greet(); // Hello

Example 2: Arrow Function with One Argument

If a function has only one argument, you can omit the parentheses. For example,

let greet = x => console.log(x);
greet('Hello'); // Hello 

Example 3: Arrow Function as an Expression

You can also dynamically create a function and use it as an expression. For example,

let age = 5;

let welcome = (age < 18) ?
  () => console.log('Baby') :
  () => console.log('Adult');

welcome(); // Baby

Example 4: Multiline Arrow Functions

If a function body has multiple statements, you need to put them inside curly brackets {}. For example,

let sum = (a, b) => {
    let result = a + b;
    return result;
}

let result1 = sum(5,7);
console.log(result1); // 12

this with Arrow Function

Inside a regular function, this keyword refers to the function where it is called.

However, this is not associated with arrow functions. Arrow function does not have its own this. So whenever you call this, it refers to its parent scope. For example,

Inside a regular function

function Person() {
    this.name = 'Jack',
    this.age = 25,
    this.sayName = function () {

        // this is accessible
        console.log(this.age);

        function innerFunc() {

            // this refers to the global object
            console.log(this.age);
            console.log(this);
        }

        innerFunc();

    }
}

let x = new Person();
x.sayName();

Output

25
undefined
Window {}

Hope this helps in improvising your JavaScript code for your Power Platform Implementations

Happy CRM’ing.

Cheers,

PMDY

addPreSearch and addCustomFilter to your lookups in Dynamics 365

Using these methods we can now easily filter the lookup in Dynamics 365.

Using addPreSearch we can specify a handler to PreSearch Event. Inside the handler we can specify our fetch xml query that can be used for filtering. The filter applied in the fetch xml will be combined with the any previously added filter as an ‘AND’ condition.

To remove the filter we can use removePreSearch method.

formContext.getControl(arg).addPreSearch(myFunction)

  1. Pass execution context
  2. Specify the argument which is nothing but the lookup field you want to addPresearch functionality.

Example:

formContext.getControl(“csz_consumedproduct”).addPreSearch(filterConsumedProductLookup);

function filterConsumedProductLookup(executionContext) {
debugger;
var entityLogicalName = “product”;
var filter = ” <filter>” +
” <condition attribute=’name’ operator=’not-like’ value=’%Accompanied%’ />” +
” </filter>”;
executionContext.getFormContext().getControl(“csz_consumedproduct”).addCustomFilter(filter, entityLogicalName)
}

Cheers,

PMDY

Cheers,

PMDY