The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
SlightlyLoony
Tera Contributor

find_real_file.pngA few days ago I was talking with someone I'll call Joe about one of our Discovery scripts. Joe was trying to figure out something we were doing in the script, and I finally figured out what was giving him trouble: he'd never run into the notion of using a JavaScript object to represent something. In the specific case he was puzzling over, we used JavaScript objects to represent network adapters — but it could have been anything at all.

For example, suppose you were writing a script that needed to refer to a few hundred locations, many thousands of times. You could do this with queries to the database, but the performance would be slower than you'd like — so you'd like to have this list in memory. Let's further suppose that your script needs to find locations by (presumably unique) name or by (not necessarily unique) zip code. How could you do this?

Here's some code that will do the trick:


var locations = getLocations();

var sd = locations.byName['San Diego'];
gs.log('San Diego: ' + sd.street + ', ' + sd.city + ' ' + sd.zip);

var zip92075 = locations.byZip['92075'];
for (var i = 0; i < zip92075.length; i++) {
var item = zip92075;
gs.log(item.name + ': ' + item.street + ', ' + item.city + ' ' + item.zip);
}


// build the locations object...
function getLocations() {
var answer = {};
answer.locations = [];
answer.byName = {};
answer.byZip = {};

var gr = new GlideRecord('cmn_location');
gr.query();
while (gr.next()) {
// make our object representing a location...
var location = {};
location.name = '' + gr.name;
location.street = '' + gr.street;
location.city = '' + gr.city;
location.zip = '' + gr.zip;
location.country = '' + gr.country;
location.company = '' + gr.company;

// store our new location in a list...
answer.locations.push(location);

// add it to our map of locations by (unique) name...
answer.byName[location.name] = location;

// add it to our map of locations by (not unique) zip code...
if (!answer.byZip[location.zip])
answer.byZip[location.zip] = [];
answer.byZip[location.zip].push(location);
}
return answer;
}

When I run this script on my instance, here's the result:

San Diego: 100 Park Boulevard, San Diego 92101
San Diego North: 937 Lomas Santa Fe Drive, San Diego 92075
San Diego West: 123 West Plaza, Solana Beach 92075

So what's going on here?

The first ten lines or so of the script just invokes the getLocations() function and demonstrates that the result does, in fact, do what we need. All the interesting stuff is in that function.

The first thing the function does is to create an answer object — the value that will be returned by the function. In that answer object, we create three properties:
  • locations: a simple array of locations (more on these later)
  • byName: an object whose properties are named for the names of locations, and the values are the locations by that name
  • byZip: an object whose properties are named for the zip codes of locations, and the values are arrays of locations at that zip code

Then the function queries the location table and iterates through the results. In the for loop, the first thing it does is to create an object representing the location in the current row. Each property in this object is named for some aspect of a location that we want to store and use (name, street, zip, etc.). Then it takes the shiny new location object and does three things with it:
  1. add to list: pushes the new location onto the end of the list of locations
  2. add to byName object: stores the new location to the property in byName named as the location name
  3. add to byZip object: first checks to see if it needs to create a property for this location's zip code (and if so, creates the property with an empty array as a value), then pushes the new location onto the end of that array

These general techniques can be used to represent absolutely anything in a generic JavaScript object. Even if what you need to represent is hierarchical (such as representing computers and their associated network adapters), it's still easy: you can have an object that represents a computer, and within that object have a property (named, say, nics) that contains an array of objects representing network adapters. By putting pieces like this — each individually rather simple — together, you can create arbitrarily complex objects to hold anything you need to hold, in a way that's easy and fast to get to...

Oh, and if you're wondering what's up with that sculpture...