Computed Fields
Auto-calculating fields that update automatically when their dependencies change - like Excel formulas for your forms.
What Are Computed Fields?
Computed fields are automatic calculations that update whenever their dependencies change. They're perfect for totals, percentages, string concatenation, and any value that can be derived from other fields.
When to Use
✅Use For:
- • Simple math (price × quantity)
- • Percentages (subtotal × tax rate)
- • String operations (firstName + lastName)
- • Rounding numbers
- • Min/max values
- • Simple conditionals
❌Don't Use For:
- • API calls
- • Complex logic with loops
- • Array transformations
- • Multiple steps of logic
- • Error handling
- • Async operations
Basic Structure
{
"computedFields": {
"fieldName": {
"targetPath": "where.to.store.result",
"expression": "context.field1 * context.field2",
"dependencies": ["field1", "field2"]
}
}
}The Three Parts:
1. targetPath
Where to store the result in your context
"targetPath": "order.total"2. expression
The calculation to perform (must use context. prefix)
"expression": "context.price * context.quantity"3. dependencies
Fields that trigger recalculation when they change
"dependencies": ["price", "quantity"]Complete Example: Shopping Cart
{
"context": {
"cart": {
"price": 100,
"quantity": 1,
"subtotal": 0,
"taxRate": 0.08,
"tax": 0,
"total": 0
}
},
"computedFields": {
"subtotal": {
"targetPath": "cart.subtotal",
"expression": "context.cart.price * context.cart.quantity",
"dependencies": ["cart.price", "cart.quantity"]
},
"tax": {
"targetPath": "cart.tax",
"expression": "Math.round(context.cart.subtotal * context.cart.taxRate * 100) / 100",
"dependencies": ["cart.subtotal", "cart.taxRate"]
},
"total": {
"targetPath": "cart.total",
"expression": "context.cart.subtotal + context.cart.tax",
"dependencies": ["cart.subtotal", "cart.tax"]
}
}
}✨ What Happens:
- 1. User changes
pricefrom 100 to 150 - 2.
subtotalrecalculates: 150 × 1 = 150 - 3.
taxrecalculates: 150 × 0.08 = 12 - 4.
totalrecalculates: 150 + 12 = 162 - All automatically! No manual updates needed.
Expression Syntax
Supported Operations
| Category | Operators | Example |
|---|---|---|
| Arithmetic | + - * / % | context.a + context.b |
| Comparison | > < >= <= === !== | context.age >= 18 |
| Logical | && || ! | context.a && context.b |
| Ternary | ? : | context.x > 10 ? 0 : 5 |
Math Functions
// Rounding
Math.round(context.value * 100) / 100 // Round to 2 decimals
Math.floor(context.value) // Round down
Math.ceil(context.value) // Round up
// Min/Max
Math.max(0, context.value) // At least 0
Math.min(context.value, 100) // At most 100
// Other
Math.abs(context.value) // Absolute value
Math.pow(context.value, 2) // Power
Math.sqrt(context.value) // Square rootString Operations
// Concatenation
context.firstName + ' ' + context.lastName
// Methods
context.text.toUpperCase()
context.text.toLowerCase()
context.description.substring(0, 100)Common Patterns
1. Percentage Calculation
{
"discount": {
"targetPath": "order.discount",
"expression": "context.order.subtotal * (context.order.discountPercent / 100)",
"dependencies": ["order.subtotal", "order.discountPercent"]
}
}2. Conditional Calculation
{
"shipping": {
"targetPath": "order.shipping",
"expression": "context.order.total > 100 ? 0 : 9.99",
"dependencies": ["order.total"]
}
}Reads as: If total > 100, shipping is free (0), otherwise $9.99
3. Full Name
{
"fullName": {
"targetPath": "user.fullName",
"expression": "context.user.firstName + ' ' + context.user.lastName",
"dependencies": ["user.firstName", "user.lastName"]
}
}4. Tiered Calculation
{
"shippingCost": {
"targetPath": "order.shipping",
"expression": "context.order.total > 200 ? 0 : context.order.total > 100 ? 5 : 10",
"dependencies": ["order.total"]
}
}Reads as: If total > $200, free shipping. Else if > $100, $5. Otherwise $10.
Common Mistakes
❌ Mistake #1: Missing Dependency
{
"expression": "context.price * context.quantity",
"dependencies": ["price"] // ❌ Missing quantity!
}Fix: List ALL fields used in the expression
{
"expression": "context.price * context.quantity",
"dependencies": ["price", "quantity"] // ✅ All listed
}❌ Mistake #2: Forgot "context." Prefix
{
"expression": "price * quantity" // ❌ Missing context. prefix
}Fix: Always use context.
{
"expression": "context.price * context.quantity" // ✅ With context. prefix
}❌ Mistake #3: Value is Null/Undefined
{
"expression": "context.price * context.quantity" // ❌ Might fail if null
}Fix: Provide defaults
{
"expression": "(context.price || 0) * (context.quantity || 1)" // ✅ With defaults
}Live Example
When to Use Custom Functions Instead
If you need any of these, use Custom Functions instead:
- Multiple steps of logic
- API calls or async operations
- Array transformations (map, filter, reduce)
- Complex conditionals with many branches
- Error handling
- Data validation