unlocking the power of servicenow scripting: pro developer insights

ServiceNow scripting isn’t rocket science – even a developer with a few months of experience can get up to speed if they’re willing to put in the work. But here’s the secret sauce to becoming a top-tier developer: writing code that’s not just efficient and reliable, but also smartly error-handled to avoid those “oops” moments.

Want to truly stand out? It’s all about mastering the powerful APIs, methods, and knowing exactly when and how to use them. Because let’s be real, knowing what to use is half the battle – knowing when and how to use it? That’s where the magic happens.

The Hidden Gem: The "getRefRecord" Method

In the world of ServiceNow development, there are several methods that often go unnoticed, despite their tremendous potential. One such method that deserves more attention is the "getRefRecord" method.

The "getRefRecord" method proves to be extremely useful when you need to retrieve a referenced GlideRecord object and perform updates on it. This method simplifies working with related records, making it easier to interact with referenced data directly.

Example: Updating Related Problem Work Notes for a Priority 1 Incident

Let’s consider a scenario where you want to retrieve a Priority 1 incident and update its associated problem record with a note. Here’s how you can achieve that using the "getRefRecord" method:
                    
var grIncident = new GlideRecord("incident");
grIncident.addQuery("priority", 1);  // Query for priority 1 incidents
grIncident.query();

while (grIncident.next()) {
    var grProblem = grIncident.problem.getRefRecord();  // Retrieve the related problem record

    if (grProblem.isValidRecord()) {  // Ensure the problem record is valid
        grProblem.notes = "This problem is associated with a Priority 1 incident";  // Update the work notes
        grProblem.update();  // Save the changes
    }
}

                    
                

GlideRecord get Method: A Key to Efficient Data Retrieval

This method is exceptionally efficient when you are confident that your query will return only a single record, making it ideal for scenarios where you need to fetch a specific entry quickly and with minimal overhead.

The get method accepts either one or two parameters. When a single parameter is provided, it is assumed to be the Sys ID of the record you're looking for. In cases where two parameters are provided, the first is interpreted as the name of the field (column) within the GlideRecord to search, and the second is the value you're looking for in that field. This added flexibility allows for more targeted queries, enabling you to retrieve records based on different criteria beyond just the Sys ID.

Example 1: Retrieving a Record by Sys ID
                    
                    
var grIncident = new GlideRecord('incident');
if(grIncident.get('99ebb4156fa831005be8883e6b3ee4b9')) //this method returns true when found matching record
	gs.info(grIncident.number); 

Example 2: get method with multiple parameters

var grIncident = new GlideRecord('incident');
if(grIncident.get('number',"INCXXXXX")) //this method returns true when found matching record
	gs.info(grIncident.short_description);
                    
                
Note: Remember to always use this method with if condition, using method without if condition and updating record could create new entry in related table if record not found with given filter.

Unlocking the Full Potential of the g_scratchpad Object

The primary purpose of the g_scratchpad object is to access server-side data in an onLoad client script, typically through a Display Business Rule. It is especially useful when data required in the client script is not available directly on the form. This allows developers to fetch and utilize server-side data seamlessly during the form's loading process.
                        
Display BR:

(function executeRule(current, previous /*null when async*/) {
    // Access a field that is not part of the form (Assigned Group in this case)
    var assignedGroup = current.assignment_group.getDisplayValue();  // This field is not on the form
    g_scratchpad.assigned_group = assignedGroup; // Store it in g_scratchpad
})(current, previous);
                        
                    
                        
On Load Client Script:

function onLoad() {
    // Access the assigned group value from g_scratchpad
    if (g_scratchpad.assigned_group) {
        // Display the assigned group value
        alert('The Assigned Group is: ' + g_scratchpad.assigned_group);
        
        // Optionally, display it as an info message on the form
        g_form.addInfoMessage('The Assigned Group is: ' + g_scratchpad.assigned_group);
    }
}
                        
                    
However, this is not only scenario where g_scratchpad object is useful. The `g_scratchpad` object is highly versatile and can be used in a variety of scenarios beyond just validation. It is accessible across all client script types—such as UI Policies, onChange, and onSubmit client scripts—enabling developers to pass data seamlessly between these entities. This ensures smooth communication and functionality within the application. In short, `g_scratchpad` is not limited to server-to-client interactions; it also facilitates data sharing between client-side scripts.

e.g. To ensure accurate form submission validation when server-side data is needed, it's crucial to understand that GlideAjax cannot be used directly for validation in client scripts. This is because GlideAjax is asynchronous, causing the form to submit before the validation results are returned. Additionally, using GlideAjax with getXMLWait() is not considered a best practice.

A better approach is to utilize the Scratchpad object. You can store the necessary data or validation results in the Scratchpad during an onChange client script and then access it during the onSubmit client script for validation. This ensures that the required data is available at the time of form submission, allowing for reliable server-side validation without delays.

Best Practices for Null Value Verification

Null value verification: It’s the unsung hero of coding. Every developer should have it in their toolbox. And yet, most beginner developers try to tackle it like this:

    if (firstName == "") 
        gs.addInfoMessage("Please enter first name");
    
Sure, it works... most of the time. But here's the kicker: it doesn't always do the job. Why? Because in the ever-wild world of programming, "empty" doesn’t just mean one thing. It could be `null`, `undefined`, or the classic empty string (`""`). If you’re only checking one of these, you’re leaving your code vulnerable to bugs like a leaky bucket.

So, how do you guard against these elusive empty variables? Fear not—ServiceNow has your back with built-in methods that make null verification as easy as pie. Let’s dive into the magic of these options.

1. JSUtil API:

If you’re doing server-side scripting in ServiceNow, JSUtil is your secret weapon. This handy object has a couple of methods that will save you from those embarrassing moments where your code doesn’t catch an empty value. So, let’s get into it.

i) JSUtil.nil(object) method: This method is a real game-changer. It checks if an object is `null`, `undefined`, or an empty string—all in one neat little package. No need to guess or perform multiple checks. Just use `JSUtil.nil()` and breathe easy.
                        
Example:

var firstName = "ServiceNow";
var lastName = "";

if (JSUtil.nil(firstName))
    gs.print("First Name is empty");
else
    gs.print("First Name is not empty");

if (JSUtil.nil(lastName))
    gs.print("Last Name is empty");
else
    gs.print("Last Name is not empty");


Output:
First Name is not empty
Last Name is empty

Pretty straightforward, right? JSUtil.nil() covers all the bases, so you don’t have to worry about leaving any potential empty value unchecked.

ii) JSUtil.notNil(object) Method: Need the opposite? No problem. JSUtil.notNil() checks if the object is not "null", `undefined`, or an empty string. It's basically the flip side of nil(). Example:

var firstName = "ServiceNow";
var lastName = "";

if (JSUtil.notNil(firstName))
    gs.print("First Name is " + firstName);
else
    gs.print("First Name is empty");

if (JSUtil.notNil(lastName))
    gs.print("Last Name is " + lastName);
else
    gs.print("Last Name is empty");

Output:
First Name is ServiceNow
Last Name is empty


Important Note: Be aware that JSUtil isn’t available in scoped applications.

2. gs.nil() Method

Guess what? You don’t have to stop with JSUtil. gs.nil() is another nifty method that can handle null checks. It’s perfect when you're working with GlideRecord objects, but it also works on normal dot-walked variables.

Example with GlideRecord:

var grUser = new GlideRecord('sys_user');
if (grUser.get("XXXXX")) {
    if (gs.nil(grUser.first_name)) {
        gs.addInfoMessage("First name is missing!");
    }
}

Or, if you’re just checking a regular GlideRecord object:

var gr = new GlideRecord("sys_user");
gs.info(gs.nil(gr)); // This will check if the GlideRecord object itself is null or empty

3. current.name.nil()

Working with records and need a quick check? You can even use nil() directly on fields within the glideobject record.

Example:
if (current.name.nil()) {
    gs.addInfoMessage("Name field is empty");
}

4. The Simple `if (name)` Check

Finally, for client-side scripts, you can simplify things even further with a good old-fashioned `if (name)` check. This check will cover all three empty states: empty string, `undefined`, and `null`. It’s the all-in-one solution.

Example:
if (!name) {
    gs.addInfoMessage("Name is either empty, undefined, or null");
}

Powerful Error Handling: Using try-catch in Conjunction with gs.error

Most developers are familiar with the try-catch structure in programming, but many fail to use it as often as they should. The reason? Their focus is typically on completing the task at hand, and they may not see an immediate need for try-catch blocks. However, to truly elevate yourself as a professional developer, this mindset needs to change. By proactively incorporating try-catch blocks in every possible scenario, you not only safeguard your code from unexpected errors but also distinguish yourself as a developer who writes robust, error-resilient applications. This shift in approach will set you apart from the rest.

What Exactly is a Try-Catch Block?

In simple terms, a try-catch block is a safety net for your code. It’s a way of telling your program, “Hey, try running this code, but if something goes wrong, handle it gracefully without crashing the entire application.”

Here’s the basic syntax:
                    
try {
// Code that might cause an error
} catch (error) {
    // Code that handles the error
    gs.error("An error occurred in script inlcude XXXXX: " + error.message);
}

                    
                
In the try block, you put the code that might throw an error. If the code in the try block fails for any reason, the catch block is executed, and you can handle the error gracefully—whether by logging it, displaying an error message to the user, or even taking corrective actions.

Why You Should Always Use Try-Catch in Scripting

1. Prevent Your Code from Crashing
2. Improve Debugging and Troubleshooting
3. Enhance User Experience

Comments

Ritika 2025-01-31 06:30:57
Abhijit, this is an outstanding article! You’ve done an excellent job of delivering valuable insights, keep up the fantastic work! I’d love to learn more about other important functionalities like this—your content is always so informative and helpful. And a big thank you for providing the interview preparation materials. It's been an amazing platform for me, and I’m truly grateful for the support in my interview prep journey!



Pratik 2025-01-14 03:58:51
Excellent tips! I would like to know more of such important topics that I as ServiceNow developer should know






🚀 Power Up Your ServiceNow Career

Join a growing community of smart ServiceNow professionals to stay ahead in interviews, sharpen your development skills, and accelerate your career.