
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.
DIFFICULTY LEVEL: INTERMEDIATE to ADVANCED
Assumes having taken the class SSNF and has good intermediate to advanced level of knowledge and/or familiarity with Scripting in ServiceNow.
In this article I will present a couple of different methods I use to locate a record in a complex object array.
This is the third of three articles I wanted to write concerning object arrays. My previous two were:
Community Code Snippets - Three Methods to Sort an Object Array
Community Code Snippets - Removing Duplicates From an Object Array
I suggest going through those before playing with the code in this example.
Additionally, you will need to work through the following Mini-Labs in order to use underscore.js and the JavaScriptExtensions code:
Mini-Lab: Adding Underscore.js Into ServiceNow
Mini-Lab: Extending the JavaScript Array Object with findIndex
Preparation: Use the following code for all of the examples in this article. All of these examples are to be run in Scripts - Background.
// Set up for all of the following examples. Get 10 records from the Incident table
var incidentRecords = new GlideRecord('incident');
incidentRecords.setLimit(10);
incidentRecords.query();
var incidentList=[];
while(incidentRecords.next()) {
var incident = {};
incident.sys_id = incidentRecords.sys_id + '';
incident.number = incidentRecords.getValue('number');
incidentList.push(incident);
}
var incidentID = '46ee8c2fa9fe198100623592c70d643e';
gs.info(JSON.stringify(incidentList));
// ------- Code examples -------
EXAMPLE 1:
This is my preferred method. It does not require a library in Global or Scoped, and works with existing out-of-the-box ServiceNow JavaScript libraries.
// ------- Code examples -------
var incidentLocated = incidentList.filter(function(element) { return element.sys_id === incidentID; })[0];
gs.info('---> Array.filter:\n\tsys_id: {0} - {1}', [incidentLocated.sys_id, incidentLocated.number]);
This gives the following result:
*** Script: [{"sys_id":"1c741bd70b2322007518478d83673af3","number":"INC0000060"},{"sys_id":"1c832706732023002728660c4cf6a7b9","number":"INC0009002"},{"sys_id":"46b66a40a9fe198101f243dfbc79033d","number":"INC0000009"},{"sys_id":"46b9490da9fe1981003c938dab89bda3","number":"INC0000010"},{"sys_id":"46c03489a9fe19810148cd5b8cbf501e","number":"INC0000011"},{"sys_id":"46c88ac1a9fe1981014de1c831fbcf6d","number":"INC0000012"},{"sys_id":"46cebb88a9fe198101aee93734f9768b","number":"INC0000013"},{"sys_id":"46e18c0fa9fe19810066a0083f76bd56","number":"INC0000014"},{"sys_id":"46ee0924a9fe198100f1cf78c198454a","number":"INC0000021"},{"sys_id":"46ee8c2fa9fe198100623592c70d643e","number":"INC0000024"}]
*** Script: ---> Array.filter: sys_id: 46ee8c2fa9fe198100623592c70d643e - INC0000024
However, you don't get the actual index location back; if you care about it that is.
EXAMPLE 2:
So, let me demonstrate a way of doing the same thing with the underscore.js library. Here you can see that there is a way of retrieving the location of the record based on the ID.
// ------- Code examples -------
gs.include('underscorejs.min');
var indexUS = _.chain(incidentList).pluck("sys_id").indexOf(incidentID).value();
incidentUS = incidentList[indexUS];
gs.info('---> Underscore: index:{2}\n\tsys_id: {0} - {1}', [incidentUS.sys_id, incidentUS.number, indexUS]);
Produces the exact same results:
*** Script: [{"sys_id":"1c741bd70b2322007518478d83673af3","number":"INC0000060"},{"sys_id":"1c832706732023002728660c4cf6a7b9","number":"INC0009002"},{"sys_id":"46b66a40a9fe198101f243dfbc79033d","number":"INC0000009"},{"sys_id":"46b9490da9fe1981003c938dab89bda3","number":"INC0000010"},{"sys_id":"46c03489a9fe19810148cd5b8cbf501e","number":"INC0000011"},{"sys_id":"46c88ac1a9fe1981014de1c831fbcf6d","number":"INC0000012"},{"sys_id":"46cebb88a9fe198101aee93734f9768b","number":"INC0000013"},{"sys_id":"46e18c0fa9fe19810066a0083f76bd56","number":"INC0000014"},{"sys_id":"46ee0924a9fe198100f1cf78c198454a","number":"INC0000021"},{"sys_id":"46ee8c2fa9fe198100623592c70d643e","number":"INC0000024"}]
*** Script: ---> Underscore: index:9.0 sys_id: 46ee8c2fa9fe198100623592c70d643e - INC0000024
The only problem I have with this example is in maintenance. I have to comment it a bit so that it explains what exactly is happening.
EXAMPLE 3:
So finally, if you implement the new ECMA6 polyfill for Array.findIndex you get the same functionality as the underscore.js example, but it is easier to implement (and future-proof; as when ServiceNow finally implements the ECMA6 functionality).
// ------- Code examples -------
gs.include('JavaScriptExtensions');
var indexFI = incidentList.findIndex(function(element) { return element.sys_id == incidentID; });
var incidentFindIndex = incidentList[indexFI];
gs.info('---> FindIndex: index:{2}\n\tsys_id: {0} - {1}', [incidentFindIndex.sys_id, incidentFindIndex.number, indexFI]);
Produces the exact same results:
*** Script: [{"sys_id":"1c741bd70b2322007518478d83673af3","number":"INC0000060"},{"sys_id":"1c832706732023002728660c4cf6a7b9","number":"INC0009002"},{"sys_id":"46b66a40a9fe198101f243dfbc79033d","number":"INC0000009"},{"sys_id":"46b9490da9fe1981003c938dab89bda3","number":"INC0000010"},{"sys_id":"46c03489a9fe19810148cd5b8cbf501e","number":"INC0000011"},{"sys_id":"46c88ac1a9fe1981014de1c831fbcf6d","number":"INC0000012"},{"sys_id":"46cebb88a9fe198101aee93734f9768b","number":"INC0000013"},{"sys_id":"46e18c0fa9fe19810066a0083f76bd56","number":"INC0000014"},{"sys_id":"46ee0924a9fe198100f1cf78c198454a","number":"INC0000021"},{"sys_id":"46ee8c2fa9fe198100623592c70d643e","number":"INC0000024"}]
*** Script: ---> FindIndex: index:9.0 sys_id: 46ee8c2fa9fe198100623592c70d643e - INC0000024
Again, this example would require some commenting just to make it clear to a maintenance coder what is going on.
OTHER FUTURE EXAMPLES:
The following are examples that should work in a Scoped application set for ECMA6+ is implemented in ServiceNow:
// ------- Code examples -------
// ecma 6+ --- doesn't work yet ... sniff!
var incidentMap = incidentList.map(x => x.says_id).indexOf(incidentID);
gs.info('---> Map:\n\tsys_id: {0} - {1}', [incidentMap.sys_id, incidentMap.number]);
// ecma 6+ --- nor this! makes me want to weep...
var incidentFindIndex = incidentList.findIndex(x => x.sys_id === incidentID);
gs.info('---> FindIndex:\n\tsys_id: {0} - {1}', [incidentFindIndex.sys_id, incidentFindIndex.number]);
// ecma 6+ --- This works, but only in scoped apps!
var index = incidentList.reduce((i, item, index) => item.sys_id === incidentID ? index : i, -1);
var incidentIndex = incidentList[index];
gs.info('---> reduce: index: {2}\n\tsys_id: {0} - {1}', [incidentIndex.sys_id, incidentIndex.number, incidentIndex]);
Results I get when run in a scoped application:
x_0462_myniftyapp: [{"sys_id":"1c741bd70b2322007518478d83673af3","number":"INC0000060"},{"sys_id":"1c832706732023002728660c4cf6a7b9","number":"INC0009002"},{"sys_id":"46b66a40a9fe198101f243dfbc79033d","number":"INC0000009"},{"sys_id":"46b9490da9fe1981003c938dab89bda3","number":"INC0000010"},{"sys_id":"46c03489a9fe19810148cd5b8cbf501e","number":"INC0000011"},{"sys_id":"46c88ac1a9fe1981014de1c831fbcf6d","number":"INC0000012"},{"sys_id":"46cebb88a9fe198101aee93734f9768b","number":"INC0000013"},{"sys_id":"46e18c0fa9fe19810066a0083f76bd56","number":"INC0000014"},{"sys_id":"46ee0924a9fe198100f1cf78c198454a","number":"INC0000021"},{"sys_id":"46ee8c2fa9fe198100623592c70d643e","number":"INC0000024"}]
x_0462_myniftyapp: ---> Map: sys_id: undefined - undefined
x_0462_myniftyapp: ---> FindIndex: sys_id: undefined - undefined
x_0462_myniftyapp: ---> reduce: index: 9 sys_id: 46ee8c2fa9fe198100623592c70d643e - INC0000024
So, you can see that there are a several ways to retrieve a record from an object array. Explore this a bit, and you might find other ways (yes, there are more).
Some "light" additional reading on Polyfills:
https://reference.codeproject.com/javascript/reference/global_objects/array/filter
https://reference.codeproject.com/javascript/reference/global_objects/array/foreach
https://reference.codeproject.com/javascript/reference/global_objects/array/find
https://reference.codeproject.com/javascript/Reference/Global_Objects/Array/findIndex
Enjoy!
Steven Bell.
If you find this article helps you, don't forget to log in and mark it as "Helpful"!
Originally published on: 7-30-2018 08:19 PM
I updated the code and brought the article into alignment with my new formatting standard.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.