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:

  1. GlideRecord: A GlideRecord object representing the record to be checked.
  2. Encoded Query String: A string representing the filter conditions to check against (commonly seen in the conditions or filter_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:

  1. Input Variables: Set the targetRecordSysId, tableName, filterFieldName, and the recordToCheck.
  2. Retrieve Filter Record: Retrieves the record containing the encoded query.
  3. Get Encoded Query: Extracts the encoded query string from the target record's specified field.
  4. GlideFilter.checkRecord(): Calls the checkRecord method, passing in the current record and the encoded query.
  5. Conditional Logic: Executes custom logic based on whether the current record matches the filter.
  6. 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 in try...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 and gs.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.