Syntax, objects, functions, chaining, thisRow, If(), SwitchIf() — everything you need to write your first real Coda formula.
In Coda, a formula always starts with =. You can write formulas in two places — column cells and canvas cells — and they behave differently in each context.
Written in the column header. Applies automatically to every row — just like a spreadsheet column formula. You write it once; Coda runs it for every row.
= (in the column header) thisRow.[Due Date] < Today()
Written anywhere in the canvas (the document area). Standalone — it computes once, not per-row. Use for summaries, totals, dashboards.
= (in a canvas text block) Count(Tasks.Filter( [Status] = "Done"))
thisRow is available because the formula runs per row. In a canvas formula, there is no "current row" — you reference the table directly.
Every Coda formula is built from two kinds of building blocks. Once you see the grammar, reading any formula becomes much easier.
Things that exist in your doc — a table, a row, a column, a page. You reference them by name.
Examples: Tasks, thisRow, [Status]
Actions that compute or transform. Always followed by parentheses. Take arguments separated by commas.
Examples: Filter(), Count(), If()
The inputs a function needs, inside the parentheses. Could be a column reference, a string, a number, or even another formula.
Syntax: FunctionName(arg1, arg2)
| Kind | Example | What it refers to |
|---|---|---|
| Table (object) | Tasks | The Tasks table in your doc |
| Column (object) | [Status] | The Status column — use square brackets |
| Current row (object) | thisRow | The row this column formula is running on |
| Function | Filter(table, condition) | Returns rows matching the condition |
| Function | Count(list) | Counts items in a list or table |
| Function | Sum(list) | Adds all numbers in a list |
Coda supports two syntaxes for combining functions. Both produce identical results — but one is dramatically easier to read as formulas grow complex.
Functions nest inside each other like Russian dolls. Read from inside-out. Works fine for simple formulas, but becomes hard to parse quickly.
Count(Filter(Tasks, [Status] = "Done"))
Works — but you have to count parentheses to understand the structure.
Functions chain left-to-right with a dot. Read like English prose. Preferred for any formula with more than one step.
Tasks .Filter([Status] = "Done") .Count()
Same result — reads as "start with Tasks, filter to Done, count them."
Here's a more complex example that shows why chaining wins at scale:
Average(Filter(Tasks, [Assignee] = "Alice").[Estimate])
Tasks .Filter([Assignee] = "Alice") .[Estimate] .Average()
Inside a column formula, thisRow refers to whichever row the formula is currently running on. It's how you access the values in the same row — without hardcoding a row number.
thisRow — the current row being evaluated
[Due Date] — grab the Due Date value from this row
< — "is earlier than"
Today() — returns today's date dynamically
This formula placed in a Checkbox column returns true when the task's due date has already passed — giving you an instant "Overdue" flag. It updates every day automatically because Today() is dynamic.
thisRow will produce an error. In canvas formulas, reference columns via the table: Tasks.[Due Date].
Conditional formulas let a column's value change depending on other values in the row. They're the foundation of calculated status fields, dynamic labels, and traffic-light indicators.
The basic conditional. Takes three arguments: a condition, what to return when true, and what to return when false.
If() — evaluates a condition
thisRow.[Status] = "Done" — true or false?
"✓" — returned when condition is true
"○" — returned when condition is false
When you have more than two cases, nesting If() inside If() gets messy fast. SwitchIf() handles multiple branches cleanly — condition/value pairs, with an optional final fallback.
SwitchIf( thisRow.[Priority] = "High", "🔴", thisRow.[Priority] = "Medium", "🟡", "🟢" // fallback — everything else is Low )
SwitchIf(condition1, value1, condition2, value2, fallback) — pairs of condition/value, ending with an optional fallback. Much cleaner than If(cond1, val1, If(cond2, val2, fallback)) for three or more cases.
Let's put it all together. Here's a real-world column formula for a "Status Icon" column that combines chaining, thisRow, and SwitchIf.
| Task | Status Select | Due Date Date | Status Icon Formula |
|---|---|---|---|
| Write landing page | Done | Apr 10 | ✅ |
| Design mockups | Blocked | Apr 12 | 🔴 |
| Send proposals | To Do | Mar 28 | ⚠️ |
| Review analytics | To Do | May 5 | ⬜ |
SwitchIf() — evaluates condition/value pairs in order; first match wins
thisRow.[Column]
Today() recalculates daily — overdue tasks auto-flag without any manual update
"⬜" is the last argument — returned when no condition matched