The Mighty Script Include

I'm lazy and proud!

Some years ago, I had just landed my first real web development job. I didn't know much, and figured I should probably buy a book. The first and only book I bought, I found a philosophy on the first page. While I have forgotten the name of the book, and and even the exact words it said. I do remember the philosophy that it instilled in me.

"Developers are inherently lazy"

While this might make some managers cringe when they hear it, or be an embarrassment to some, I take it as a point of pride and have tried to follow it, through my entire career.

Let me explain this concept a little further so I don't give my boss a mild heart attack. To me, I've internalized it as a method of finding the best and most efficient way to accomplish a task. This is also include keeping things simple, not duplicating work, and making my life easy. It only takes a single DB wipe in production, or destroying an entire web site once to really understand it.

Let's get real for a minute... 

So what does this have to do with script includes you ask, and how can I [the reader] become lazy like you? 

Easy, send $19.99 to...errr wait...just kidding...

Basically, what I'm going to show you is something I refer to as the DAO [data access object]. It's my heavy lifting, organized, centralized super script. 

Go a head and create a new script include, call it whatever you want. I tend to do something like 'name_DAO', but that's not a requirement. When you're done it should look something like this:

Screen Shot 2018-01-27 at 3.54.43 PM.png

Because, I've been working within CSM most recently, I'm going to build out some different things within that application, don't worry if you don't have it installed, the concepts are the same across the platform and can be easily modified to fit other areas.

Consumers and Assets

Let's create a function to grab all the assets belonging to a consumer. I'm going to cheat and hard code the consumer, but you could use something like gs.getUserID(); to get the currently logged in user in it's place.

Some of you may have noticed a bit of code that is commented out, I'll go over that later. For now, let's concentrate on how I can access this from the portal.

It takes 2

So there are 2 methods to accessing the script include from the portal, I'll walk you through each method. We'll need to build a widget to do this so let's head over to:

Service Portal -> Widgets

Go ahead and give it a name, I'll be using "My Assets", and it's nothing more than a simple list. 


Method 1 is to call it directly from the Service Portal. So in our new widget, in the Server Side script, let's add a new line.

You can see this is a very simple method of calling the script include. You'll see that like initializing a new GlideRecord you do the same thing with your script include. Then you add the method [function] to it with the variable you are passing to it.

That's it! 

See, very simple. But are you thinking about how this fits into the lazy philosophy yet? No, that's okay, I'll give you a hint:

Something I hate doing is writing the same code multiple times. 

Basically, I can centralize code in the script include and now I can call it from any widget without having to write it multiple times. 


Method 2 is an indirect method, because we need to add another layer in calling the script include. Some may not be familiar with this method, but it opens up a new world in how dynamic you can make the portal.

Under normal circumstances, you update the widget through the server code by calling c.server.update() but let's say you want to update something on the widget without running a complete server side update. This can be handled by utilizing AngularJS's $http service and ServiceNow's script API service. This will involve creating a scripted rest api so let's head over to:

System Web Services -> Scripted REST APIs

Go ahead and create a new one, I'm calling mine "awesome_API". There's another step here though, scroll down to "Resources" and click "New". I'll be calling the resource, "getAssetsByUserID".

It should look something like this:

Screen Shot 2018-01-28 at 3.32.00 PM.png

The script should look something like this:

Now that we have that out of the way, let's write the code to handle the $http service. Let's go back to the widget we built before. I'm going to add a few things, and just like on the old cooking shows, it'll magically appear below after no time at all.

Let's start with the Client Side script

Now let's look at the Template.

You're probably asking yourself, Hey what about the server code? Well, I didn't actually change it. It's still the same. Are you starting to see the beauty here?

Back to the begining

So I had a little bit of code that was commented out back at the begining. I want to revisit that and explain a third way to access the script include. This isn't specific to the Service Portal, but allows you to use the script include from the platform side, and rounds out the versitility of the script include.

If you need to do something like a GlideAjax call you know that you pass the function with parameters. This is normally handled on the client side like this:

Then with the server side you can use the commented out code from above to allow for passing the variable from the above method.

Round it out

So I hope this has illustrated the versitility of the script include for use in the Service Portal and ServiceNow platform. So get out there, and make ServiceNow awesome!

Topics: Service Portal, Script Include, AngularJS, GlideAjax, widgets, $http, DAO, GlideRecord, code, developer