FujiForty - There's no "u" in fieldname

Final_2013_Fencing_WCH_FMS-IN_t200112.jpg

If you haven’t heard yet, Fuji introduces a new concept of application fencing. This allows for tighter control of what each application and it’s process can do. In the past, any process on the platform could access any data on the platform as long as it passed user security checks. This can present stability concerns when building custom applications and especially when installing 3rd party applications from the upcoming marketplace.

These application boundaries are defined by application scopes. You’ll hear much more about scopes and many of the changes and challenges they present throughout the FujiForty series. For now we’re going to start with something relatively small.

In the past all customer, partner, and vendor built tables and fields were prefixed with “u_” to identify them as user created data elements. With the introduction of scopes this is no longer needed as the table is owned by an application scope so it's clear where it came from. All tables are now prefixed with the application's scope name and field name are as exactly as you label them.

This certainly makes scripting field data a little cleaner. Plus, it's so much more efficient as you're saving 2 characters every time you reference a field name in a script.

Interesting thing I found today is this can present a problem if you happen to create a field name that is also a script keyword. More importantly, it gives me a reason to explain one of my scripting best practices.

I created a field called “package”, which happens to be a JavaScript keyword. This isn’t a common problem you'll run into but I mainly wanted to demonstrate various methods of accessing GlideRecord elements since it came up.

Let’s see where this would fail. Here's a script to get the value from my new "package" field.

var gr = new GlideRecord("x_myscope_mytable");
gr.get("01c457604ff271002e1f7d2ca310c767”);
gs.debug("Package: " + gr.package);

The result is:  Javascript compiler exception: missing name after . operator (<refname>; line 3)

In the previous example we are accessing the field as a property on the GlideRecord object. But JavaScript is confused since it's also a keyword. We could also access an object's property using:

gs.debug("Package: " + gr["package"]);

This would work just fine, although you don't see too much of this standard used in other ServiceNow scripts since it's just easier to access the property with dot-notation.

Here's my standard way to access a field value, regardless of the concern for keywords or anything else.

gs.debug("Package: " + gr.getValue("package"));

Here we're using the getValue method of GlideRecord to access the field value. You'll never run into issues that we first ran into. There's also another benefit of using this method. You actually get a real value, and not an object pointer. What does this mean?

Try running this in background scripts

//array to store incident numbers
var myIncidents = []; 

//get incidents
var gr = new GlideRecord("incident");
gr.setLimit(5);
gr.query();
while (gr.next()) {
   gs.debug(gr.number);
   myIncidents.push(gr.number);
}
gs.debug("myIncidents array: " + myIncidents.toString());

*** Script: [DEBUG] INC0000001
*** Script: [DEBUG] INC0000002
*** Script: [DEBUG] INC0000003
*** Script: [DEBUG] INC0000004
*** Script: [DEBUG] INC0000005
*** Script: [DEBUG] myIncidents array: INC0000005,INC0000005,INC0000005,INC0000005,INC0000005

What the what?

We pushed gr.number, which is really a pointer to the GlideRecord's number property, into the array and not the value of each incident's package field. Since the array has 5 pointers to gr.number, every time we get the next record, the pointer also moves with us and eventually ends on the last record.

Now try using the getValue method.

//array to store incident numbers
var myIncidents = []; 

//get incidents
var gr = new GlideRecord("incident");
gr.setLimit(5);
gr.query();
while (gr.next()) {
   gs.debug(gr.number);
  //push a string, not a pointer
   myIncidents.push(gr.getValue("number")); 
}
gs.debug("myIncidents array: " + myIncidents.toString());

*** Script: [DEBUG] INC0000001
*** Script: [DEBUG] INC0000002
*** Script: [DEBUG] INC0000003
*** Script: [DEBUG] INC0000004
*** Script: [DEBUG] INC0000005
*** Script: [DEBUG] myIncidents array: INC0000001,INC0000002,INC0000003,INC0000004,INC0000005

Now this is what we were expecting.

I know it's not exactly Fuji specific but it's one of the most common mistakes ServiceNow scripters can make. The good news is that it will only happen once since you'll pull your hair out trying to figure out what's happening if you don't have an OO development background.

Get it out of the way now so you don't have to worry about it when you're running up against a delivery deadline.