Using GlideFilter for Dynamic Filter Checks - ben-vargas/servicenow-wiki GitHub Wiki
This article explains how to use the GlideFilter
API in ServiceNow to check if a record matches a filter defined elsewhere in the platform. This is particularly useful for implementing dynamic logic where decisions need to be made based on filter conditions defined on other records, such as business rules, UI policies, or client scripts.
Important Note: This article discusses the use of an undocumented API (GlideFilter
). While this API is generally stable, it's important to note that undocumented APIs are subject to change or removal in future ServiceNow releases. It's recommended to use them with caution and include appropriate error handling.
The Challenge
Often, you need to evaluate if a record meets a set of criteria defined in a dynamic filter. For example, you might need to determine if an incident matches the filter conditions set on a specific business rule or UI policy. Doing this efficiently and dynamically can be difficult using standard GlideRecord queries alone, especially if the filter uses dynamic values (e.g., "Me" or "My Group").
The Solution
The GlideFilter
API provides a way to check if a record satisfies an encoded query string. The API consists of the static method checkRecord()
, which takes two arguments:
- GlideRecord: A GlideRecord object representing the record to be checked.
- Encoded Query String: A string representing the filter conditions to check against (commonly seen in the
conditions
orfilter_conditions
field).
Understanding Encoded Queries
Encoded queries represent filter conditions as a string. Here’s an example:
nameSTARTSWITHti^active=true^NQcityNOT LIKEpickles
This encoded query contains three conditions
nameSTARTSWITHti
: The 'name' field starts with 'ti'.active=true
: The record is active.cityNOT LIKEpickles
: The 'city' field does not contain 'pickles'.
The ^
symbol acts as an "AND", while ^NQ
indicates a "New Query" (used to create more complex conditions that are treated as subqueries).
Retrieving Encoded Queries
Encoded queries are used in various parts of ServiceNow. You can extract them from:
- Condition Builders: Right-click on the last condition and select "Copy Query."
conditions
field: This is a common field to contain an encoded query, often used by UI policies and Business Rules.filter_conditions
field: This field is commonly used by business rules to store their conditions.- Client-side (Browser Console): Use
console.log(getFilter('element.sys_script.filter_condition'));
to retrieve the encoded query from the condition builder of a specific element ID. - Client-Side (g_form): Use
g_form.getValue('filter_conditions')
to get the value of the field storing the encoded query on the form.
Example: Using GlideFilter in a Server-Side Script
Here's how to use GlideFilter.checkRecord()
in a server-side script:
(function() {
// Input Variables
var targetRecordSysId = 'SYS_ID_GOES_HERE'; // Sys_id of the record to check against the filter
var tableName = 'sys_script'; // Table of the record that contains the filter
var filterFieldName = 'filter_conditions'; // Field where the encoded query is stored.
var recordToCheck = current; // Record to check against the filter
try {
var filterRecord = new GlideRecord(tableName);
if (!filterRecord.get(targetRecordSysId)) {
gs.error("Could not find a record from table " + tableName + " with sys_id " + targetRecordSysId)
return; // Exit if filter record is not found
}
var encodedQuery = filterRecord.getValue(filterFieldName);
if (GlideFilter.checkRecord(recordToCheck, encodedQuery)) {
gs.info('The record matches the filter condition');
// Add your logic to process matching records.
} else {
gs.info('The record does not match the filter condition');
}
}
catch (ex) {
gs.error('An error occurred when checking record with GlideFilter: ' + ex.message);
// Optional: Code for handling errors with GlideFilter
}
})();
Explanation:
- Input Variables: Set the
targetRecordSysId
,tableName
,filterFieldName
, and therecordToCheck
. - Retrieve Filter Record: Retrieves the record containing the encoded query.
- Get Encoded Query: Extracts the encoded query string from the target record's specified field.
GlideFilter.checkRecord()
: Calls thecheckRecord
method, passing in the current record and the encoded query.- Conditional Logic: Executes custom logic based on whether the current record matches the filter.
- Error Handling: The logic is contained within a try/catch block to handle any errors, or issues that might occur with this undocumented API.
Dynamic Filter Options:
When using dynamic filter options (e.g., "Me," "My Group"), ServiceNow resolves them dynamically when the query is executed. For example, a condition like assigned_toDYNAMIC90d1921e5f510100a9ad2572f2b477fe^EQ
will be replaced with the sys_id of the current user via the script in the dynamic filter option (sys_filter_option_dynamic
) with that id.
Client-Side Example
While you can't directly use GlideFilter
in client scripts, you can use a Script Include to perform the server-side logic, and then return the result back to the client via a GlideAjax
call.
Best Practices
- Error Handling: Always wrap calls to
GlideFilter
intry...catch
blocks to handle potential errors gracefully, and include a log statement. - Undocumented API Caution: Be aware that
GlideFilter
is undocumented and could change in future releases. Keep a watchful eye on your instances during upgrades. - Performance: Test performance, especially if used in loops, or on large data sets.
- Script Includes: Use a script include to contain the logic for cleaner code and better reusability.
- Logging: Use
gs.info
andgs.error
for debugging to track the results of the GlideFilter calls. - Specificity: If possible use a direct query in a script, instead of relying on another records filter. Using a direct query is more performant, and easier to track.
Conclusion
The GlideFilter
API, despite being undocumented, is a powerful tool for implementing complex dynamic filtering logic in ServiceNow. By understanding encoded queries and using GlideFilter.checkRecord()
, you can build more dynamic and responsive applications. However, it's essential to use it cautiously, following the best practices, and with a fallback plan in case this API is deprecated or changed in the future.