Why Semicolons Matter in Dynamics 365 JavaScript

 


When writing JavaScript for Dynamics 365 / Dataverse forms, semicolons are not just style preferences — they are defensive coding tools. A single missing semicolon can silently break your form, prevent events from firing, or stop your Custom API calls from executing.

In this post, we’ll walk through real CRM-style examples, explain why semicolons are required, and show what can go wrong if you skip them.


1️⃣ Namespaces: The Foundation of CRM JavaScript

In Dynamics, we avoid global pollution by using namespaces.

✅ Correct Pattern

var DCash = DCash || {}; DCash.ItemsUploadJob = DCash.LinkItemsUploadJob || {};

Why this works

  • DCash || {} ensures the object exists

  • Prevents conflicts with other scripts

  • Supports large projects with multiple JS files

✔ Semicolons are required because these are variable assignments




3️⃣ Function Expressions (Most Common CRM Pattern)

This is where many CRM developers make mistakes.

✅ Correct

DCash.LinkItemsUploadJob.callCustomAction = function (functionName, id, userId, formContext) { "use strict"; var jsonObj = { id: id, userId: userId }; var jsonString = JSON.stringify(jsonObj); };

Why the semicolon matters

This is not a function declaration.
It’s a function expression assigned to a property.

Internally, JavaScript sees this as:

DCash.LinkItemsUploadJob.callCustomAction = (function(){});

➡️ Assignment statement → must end with ;


4️⃣ What Happens If You Forget the Semicolon ❌

DCash.LinkItemsUploadJob.callCustomAction = function () { // logic } DCash.LinkItemsUploadJob.OnSave = function () { // logic };

JavaScript may interpret this as:

}DCash.LinkItemsUploadJob.OnSave = function () {

πŸ’₯ Result:

  • Script fails silently

  • OnSave never fires

  • No console error (worst part!)


5️⃣ OnSave Event Example (Real Dynamics Scenario)

DCash.LinkItemsUploadJob.OnSave = function (executionContext) { "use strict"; var formContext = executionContext.getFormContext(); var statusCode = formContext.getAttribute("statuscode").getValue(); if (statusCode === DCash.LinkItemsUploadJob.Process) { Xrm.Utility.showProgressIndicator("Uploading Link Items..."); DCash.LinkItemsUploadJob.callCustomAction( "ProcessLinkItems", formContext.data.entity.getId(), formContext.context.getUserId(), formContext ); } };

✔ Ends with semicolon
✔ Safe for form events
✔ Production-ready


6️⃣ Function Declaration vs Function Expression

Function Declaration (No semicolon)

function showMessage() { console.log("Hello"); }

✔ Hoisted
✔ Rarely used in CRM scripts


Function Expression (CRM Standard)

DCash.showMessage = function () { console.log("Hello"); };

✔ Assigned to namespace
✔ Semicolon required


7️⃣ Return Statement Gotcha (Classic Bug)

❌ Wrong

return { success: true };

JavaScript interprets it as:

return;

✅ Correct

return { success: true };

⚠ This bug happens because of automatic semicolon insertion (ASI)


8️⃣ Xrm.WebApi Example (Custom API Call)

var request = { ActionName: "ProcessLinkItems", JsonParameters: jsonString, getMetadata: function () { return { boundParameter: null, parameterTypes: { "ActionName": { typeName: "Edm.String", structuralProperty: 1 }, "JsonParameters": { typeName: "Edm.String", structuralProperty: 1 } }, operationType: 0, operationName: "new_TriggerPowerAutomate" }; } }; Xrm.WebApi.execute(request).then( function success(response) { return response.json(); } ).catch(function (error) { console.error(error.message); });

✔ Object literals → semicolons
✔ Function expressions → semicolons

Comments

Popular posts from this blog

πŸ” Dataverse + Azure Integration: Choosing Between Synapse Link and Microsoft Fabric

⚡ Example: Rate Limiting in Azure API Management

In-Process vs Isolated Process Azure Functions: What’s the Difference?