The oldValue parameter in onChange client scripts gives you the field's value before the user's change, but it's undefined during form load — even for existing records with data. Most developers assume oldValue will contain the database value when editing existing records, but it only captures values after the form has loaded and the user makes their first change. This behavior exists because the client script engine doesn't populate oldValue until after the first user interaction with each field.

When to use this

  • When you need to compare before and after values to trigger conditional logic in real-time
  • When building audit trails or change notifications that must fire immediately on field changes
  • When implementing field validation that depends on the transition between specific values
  • When you need to show contextual messages about what changed during the user's current session

When NOT to use this

  • Don't rely on oldValue for business rules that must capture all changes — use previous object in server-side business rules instead
  • Don't use this when you need the original database value on form load — use g_scratchpad populated by a display business rule
  • Don't use this for complex field interdependencies — use onSubmit validation where you can check multiple field states together
  • Don't process onChange events during isLoading — you'll get false positives from form population

Key behaviors and gotchas

  • The full onChange signature is (control, oldValue, newValue, isLoading, isTemplate) — always check isLoading and isTemplate before processing
  • For reference fields, oldValue contains the sys_id, not the display value — use getReference() to get display values for comparison
  • Choice field oldValue contains the actual choice value (like '2' for In Progress), not the display label
  • Empty reference fields return empty string '' in oldValue, not null or undefined
  • Date/time fields in oldValue are formatted strings in the user's session format, not raw database values
  • Multiple rapid changes to the same field will have oldValue as the value from the previous onChange, not the original form load value
⚠️

Never assume oldValue exists without checking — it's undefined on form load even for existing records. Always use typeof oldValue === 'undefined' before attempting to use the value, or your onChange logic will fail silently on the user's first field interaction.

Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime