Expressions
Expressions are JavaScript, evaluated per row. One expression, one value — like a spreadsheet formula, and with the same trust model in the browser.
They appear in six places: a field mapping in formula mode, a match rule’s value, a row filter, a module gate (Only import when…), an update guard (…update only when), and a helper library.
What is in scope
Section titled “What is in scope”row |
The source row, by column name. |
helpers |
Functions from the built-in library and your org’s own. |
rec |
Records written earlier in this row, by module singular. |
old, next |
Update guards only: the matched record, and what would be written. |
rec is the default; the name is configurable per org, so yours may differ. See Curating
modules.
row["Account No"]row.CompanyBracket notation for anything with a space or punctuation in it, which is most real-world column headings.
A missing column is undefined, not an error, so row.Nickname || '' does what you would expect.
helpers
Section titled “helpers”The built-in library, available everywhere:
| Helper | Does |
|---|---|
helpers.join(sep, ...values) |
Join the non-blank values with a separator. |
helpers.split(value, delimiter, index?) |
Split and return one trimmed part. |
helpers.date(value, inputFormat?) |
Parse a date to the destination’s format. |
helpers.num(value) |
Parse a number leniently. |
helpers.bool(value) |
True for yes / true / 1 / y, case-insensitive. |
helpers.proper(value) |
Title-case each word. |
helpers.upper(value) / helpers.lower(value) |
Change case. |
helpers.trim(value) |
Trim surrounding whitespace. |
helpers.digits(value) |
Keep only the digits. |
helpers.fallback(value, default) |
The value, or a default when it is blank. |
helpers.map(value, mapping) |
Translate through a lookup object; unknown values pass through. |
helpers.today() |
Today’s date as YYYY-MM-DD. |
Your org can add its own, under its own namespace — see Helper libraries.
helpers.join(', ', row.City, row.State, row.Postcode)helpers.digits(row.Phone)helpers.fallback(row.Owner, 'Unassigned')rec — records written earlier in this row
Section titled “rec — records written earlier in this row”When a row writes to several modules, an expression on a later module can read what the earlier ones produced:
rec.Account.idEarlier means earlier. Only modules written before this one in the row are available; a reference to a later one is always empty, and validation says so rather than letting it fail silently at run time.
The order comes from the links you mapped, and is shown on the Match step.
Outside a live run — in the formula editor, in a validation probe — rec yields a readable
placeholder rather than throwing, so an expression still previews before there is anything to
reference.
old and next — update guards only
Section titled “old and next — update guards only”An update guard decides whether an update goes ahead:
next.Phone && next.Phone !== old.Phoneold is the record as it stands in the CRM. next is what would be written. This is how you say
“do not blank a value because this file’s column is empty” or “do not downgrade a status”.
A guard that returns false downgrades the write to a skip. A guard that throws fails closed — the record is not updated. That is the safe direction: a broken guard should not wave writes through.
Where each context is available
Section titled “Where each context is available”row |
helpers |
rec |
old / next |
|
|---|---|---|---|---|
| Field mapping | ✓ | ✓ | ✓ | · |
| Match rule value | ✓ | ✓ | · | · |
| Row filter | ✓ | ✓ | · | · |
| Module gate | ✓ | ✓ | ✓ | · |
| Update guard | ✓ | ✓ | ✓ | ✓ |
A row filter cannot read rec. The file is filtered before any record exists, so the reference
could never resolve. Use a module gate instead, which runs per module with earlier records
available.
A match rule cannot read rec either: the match check runs before this row has written
anything.
Both are caught at validation rather than at the row.
What is deliberately absent
Section titled “What is deliberately absent”No network. No filesystem. No clock beyond helpers.today(). No access to other rows.
An expression sees this row and nothing else, which is what makes a formula’s behaviour something you can reason about from the file in front of you.
Errors
Section titled “Errors”An expression that throws produces an error for that row, with the message, rather than stopping the run. It shows up on the results grid against the row it happened on.
An expression that does not compile is an error at validation — the run will not start.
Blank is a value. An expression returning null, undefined or '' writes an empty field, which
is often what you want and occasionally a surprise; the Validate step warns
when a field will import empty on a large share of rows.
Writing them
Section titled “Writing them”The f(x) button anywhere an expression is accepted opens the formula editor, which runs your
expression against real rows from your file as you type. Use it — a formula that looks right and a
formula that produces the right value on row 200 are different claims.
Where AI is configured, formula assist writes one from a question in plain English. The expression is compiled and run against your samples before you see it, so what comes back at least executes. See What the AI does.