Running @Formula from SSJS: session.evaluate — Its Vector Return, Limits, and Why It Can't Change a Document
You already have a piece of Formula logic — an @DbLookup, an @Name call to format a name — and in XPages you’d rather not rewrite the whole thing in SSJS. session.evaluate() is for exactly that: run a Formula string straight from SSJS and get the result back.
But it has sharp edges worth knowing: it returns a Vector (not the scalar you might expect), field references need the document passed in, UI @functions don’t work in it, and — the one that surprises people — it can’t change a document, only compute a result.
This piece lays out session.evaluate’s two forms, its return and limits.
TL;DR
session.evaluate(formula)→java.util.Vector: results come back in a Vector, with a scalar result in the first element (firstElement).- Formula references a field → use the two-arg
evaluate(formula, doc): pass the document as the second argument so the formula can read field values. - UI @functions don’t work:
@Command,@Prompt,@PickList,@DialogBox,@PostedCommand,@DbName,@DbTitle,@ViewTitle,@DDE*,@DbManagerall fail inside evaluate. - It can’t change a document: HCL says “You cannot change a document with evaluate; you can only get a result” — to persist, write the result back with
replaceItemValue. - SSJS already exposes many @functions natively: lots of @functions can be called directly in SSJS, no evaluate needed.
- Use it to reuse existing Formula (lookups, name formatting) without porting it to SSJS.
session.evaluate: run a Formula, get a Vector
The official evaluate (Session) has two signatures:
public java.util.Vector evaluate(String formula)public java.util.Vector evaluate(String formula, Document doc)The return is always a java.util.Vector — “A scalar result is returned in firstElement.” So even when your formula computes a single value, read it from the first element:
var v = session.evaluate("@Name([Abbreviate]; @UserName)");var name = v.firstElement(); // scalar result is in the first elementPass the document: when the formula references fields
As soon as a formula mentions a field name, use the two-arg form with the document, or it can’t resolve the values:
var doc = currentDocument.getDocument(); // or any NotesDocumentvar total = session.evaluate("Qty * UnitPrice", doc).firstElement();Without the doc, Qty and UnitPrice have nothing to resolve against.
Two limits: UI @functions, and no document changes
(1) UI @functions fail. evaluate is back-end computation with no front-end UI, so HCL lists these UI-affecting @functions as ones that “do not work”: @Command, @DbManager, @DbName, @DbTitle, @DDEExecute, @DDEInitiate, @DDEPoke, @DDETerminate, @DialogBox, @PickList, @PostedCommand, @Prompt, @ViewTitle. To pop a dialog or drive the UI, use another path (see @Prompt / @PickList and @Command — also client front-end only).
(2) It can’t change a document. This is the one people misread. HCL’s words:
You cannot change a document with evaluate; you can only get a result. To change a document, write the result to the document with a method such as Document.replaceItemValue.
So even a formula with a FIELD X := ... won’t be written back by evaluate — it just returns a result. To persist, you take over:
var result = session.evaluate("@Trim(@Name([CN]; Owner))", doc).firstElement();doc.replaceItemValue("OwnerCN", result); // write it back yourselfSSJS already has many @functions
Not everything needs evaluate. The SSJS runtime (Server-side scripting and Global objects and functions) exposes a set of @functions you can call directly in SSJS, without wrapping them in a string for evaluate. For simple formatting or decisions, a native @function or plain SSJS is more direct; session.evaluate’s value is in reusing a whole piece of existing Formula (a dynamically-built formula string, or existing @DbLookup logic).
When to use it
- Reuse existing Formula logic (lookups, complex @formula) without porting it →
session.evaluate. - The formula is a dynamically-built string → evaluate takes a string, which fits.
- Just simple formatting / a decision → use plain SSJS or a native @function; skip evaluate.
- You need to store the result → remember evaluate only returns it;
replaceItemValueit back yourself.
What about LotusScript and Java?
- LotusScript: the counterpart is
Evaluate(NotesSession.Evaluate/ the globalEvaluate), with the same semantics — returns an array, doesn’t change the document, UI @functions don’t work. The site’s LotusScript Evaluate piece covers the LS side; this is the SSJS form. - Java:
session.evaluate(...)is itself a Java method (it’s what SSJS calls), returningjava.util.Vector, used the same way.