Server Scripting · Lesson 2.3
Business Rule conditions: is, changes and changes to
- Business Rules
- GlideSystem (gs)
Why conditions matter
A Business Rule on the Incident table with no condition runs on every single save of every incident. On a real instance, that is thousands of times a day. Most of those runs are pointless: a rule about Critical incidents has no business running when someone edits a Low priority one.
Conditions do two jobs. They make the rule correct, so it only acts in the situation it was written for. And they make it cheap, because ServiceNow checks the condition first and skips your script entirely when it does not match.
Three places a condition can live
| Where | What it looks like | Best for |
|---|---|---|
| Filter Conditions, on the When to run tab | A condition builder: pick a field, an operator and a value, no code | Most rules. Readable at a glance, and checked before anything runs |
| Condition, on the Advanced tab | One line of script that must be true, such as gs.hasRole('itil') |
Checks the builder cannot do, like roles or a call to a Script Include |
| Inside the script | An if statement around your code |
Logic that needs several steps or decides between different actions |
Work from the top down. If Filter Conditions can express it, put it there. Reach for the Condition field only when you need a little script, and keep if statements in the script for genuine decisions, not for checks that could have stopped the rule from running in the first place.
is, changes, changes to
In Filter Conditions, the operators that cause the most confusion are these three:
| Operator | What it asks | Runs when |
|---|---|---|
| is | What is the value now? | Every save where the field has that value, whether or not it changed |
| changes | Did this field get a new value in this save? | Every save where the value is different from before, whatever the new value is |
| changes to | Did the field become this value in this save? | Only the save where it was something else before and is this value now |
There is also changes from, the mirror image of changes to: it fires in the save where a field stops being a value, such as “State changes from Resolved” when someone reopens an incident.
Press Play to watch one incident saved five times, with two rules watching it: one with “is” and one with “changes to”.
Step 1 of 5 · Save 1
Save 1: a normal update
INC0010061 has Priority 3 - Moderate. An agent adds a comment and saves. Rule A has the condition "Priority is 1 - Critical". Rule B has "Priority changes to 1 - Critical". The priority is 3 before and after, so neither condition matches.
- previous.priority
- 3 - Moderate
- current.priority
- 3 - Moderate
- Rule A (is 1)
- Does not run
- Rule B (changes to 1)
- Does not run
Step 2 of 5 · Save 2
Save 2: the incident becomes Critical
The agent sets Impact and Urgency to 1 - High, so Priority becomes 1 - Critical, and saves. Rule A matches, because the priority is now 1. Rule B matches too, because the priority was not 1 before and is 1 now. Both rules run.
- previous.priority
- 3 - Moderate
- current.priority
- 1 - Critical
- Rule A (is 1)
- Runs
- Rule B (changes to 1)
- Runs
Step 3 of 5 · Save 3
Save 3: an edit while it is still Critical
Ten minutes later, someone fixes a typo in the short description and saves. The priority is still 1. Rule A runs again, because "is" only asks what the value is right now. Rule B does not, because nothing about the priority changed in this save. This is the difference that matters.
- previous.priority
- 1 - Critical
- current.priority
- 1 - Critical
- Rule A (is 1)
- Runs again
- Rule B (changes to 1)
- Does not run
Step 4 of 5 · Save 4
Save 4: the priority drops
The outage is contained and the priority is lowered to 2 - High. The new value is not 1, so Rule A does not run. Rule B does not either: the priority changed, but it changed away from 1, not to 1.
- previous.priority
- 1 - Critical
- current.priority
- 2 - High
- Rule A (is 1)
- Does not run
- Rule B (changes to 1)
- Does not run
Step 5 of 5 · Save 5
Save 5: Critical again
The problem comes back and the incident is raised to 1 - Critical once more. Both rules run, just like in save 2. Over five saves, Rule A ran three times and Rule B ran twice: once for each moment the incident actually became Critical.
- previous.priority
- 2 - High
- current.priority
- 1 - Critical
- Rule A (is 1)
- Runs (3rd time)
- Rule B (changes to 1)
- Runs (2nd time)
The pattern is worth remembering: “is” describes a state, “changes to” describes a moment. Validations and defaults usually care about a state. Notifications, work notes, escalations and anything else that should happen once usually care about a moment.
Detecting changes in a script
The same ideas exist as methods you can call on any field of currentIn a server script, the record being worked on right now, including any new values.Learn more , for the times you need them inside the Condition field or the script:
current.priority.changes() // true if Priority has a new value in this save
current.priority.changesTo(1) // true if Priority became 1 in this save
current.state.changesFrom(6) // true if State was 6 (Resolved) and now is not
You can also compare with previousIn a Business Rule, a copy of the record as it was before the current change.Learn more yourself, which is handy when you need the old value in a message:
// When: before | Update: true | Table: Incident
(function executeRule(current, previous /*null when async*/) {
if (current.priority.changes()) {
current.work_notes = 'Priority changed from ' + previous.priority.getDisplayValue() +
' to ' + current.priority.getDisplayValue() + '.';
}
})(current, previous);
All of these depend on knowing the value before the save, so they only work in before and after rules. In an async rule, previous is not available, as you saw in the previous lesson.
See it in your instance
- Open the Remind on P1 incident Business Rule you built in What is a Business Rule?. If you did not build it, follow that lesson’s steps first.
- On the When to run tab, change the filter condition from Priority changes to 1 - Critical to Priority is 1 - Critical and select Update.
- Open an incident that is already Priority 1 and save it without changing anything. The reminder appears. Save again: it appears again, every time.
- Change the condition back to changes to and save the rule. Repeat the test: now the reminder appears only in the save where the incident becomes Priority 1.
Practice: which condition would you use?
"is" checks a value on every save. "changes to" fires once, at the moment a field becomes a value. "changes" fires whenever a field gets any new value. Pick the right one for each rule.
Email the caller once when their incident is resolved.
Answer: changes to. "State changes to Resolved" fires only in the save where it becomes Resolved. With "is", every later edit to a resolved incident would send another email.
Add a work note every time the incident is moved to a different assignment group.
Answer: changes. Any move counts, whichever group it goes to, so "Assignment group changes" is the right fit.
A before rule that fills in a default category on every save where Category is empty.
Answer: is. You want it every time the field is empty, not only at the moment it became empty. "Category is empty" checks the current state on each save.
Flag an incident as escalated at the moment its priority becomes 1 - Critical.
Answer: changes to. Escalation is a moment, not a state you re-check on every save. "Priority changes to 1 - Critical" fires exactly then.
A validation rule that runs on every save of a Network incident to check the configuration item is filled in.
Answer: is. The check applies to every save while the category is Network, so "Category is Network" is correct here.
Notify the person newly assigned whenever Assigned to is set to someone different.
Answer: changes. You care about any new assignee, whoever it is. "Assigned to changes" catches every reassignment.
Start counting on-hold time at the moment State becomes On Hold.
Answer: changes to. The clock should start once, when it goes on hold. Editing an on-hold incident must not restart it.
Write an audit note whenever Priority is modified, up or down.
Answer: changes. Both directions count, so you want any change to Priority, not a change to one particular value.
What’s next
You can now choose between “is”, “changes” and “changes to”, put conditions in the right place, and detect changes in a script. In the next lesson, Script Includes, you will learn where to put logic that more than one rule needs, so you write it once and call it from anywhere.
Quick check
A Business Rule on Incident runs on Update with the filter condition 'State is Resolved'. An agent opens an incident that was resolved yesterday, adds a work note and saves. Does the rule run?
Show answer
Yes
“is” only checks the value at the moment of the save, and the State is still Resolved, so the rule runs, even though nothing about the State changed. If the rule should run only when an incident gets resolved, the condition should be “State changes to Resolved”.
Was this lesson helpful?
Thanks! Glad it helped. 🙌
Thank you. We will use this to improve the lesson.
Spotted a mistake, or a step that looks different in your instance?