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

json
{
  "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

json
{
  "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. 1. User changes price from 100 to 150
  2. 2. subtotal recalculates: 150 × 1 = 150
  3. 3. tax recalculates: 150 × 0.08 = 12
  4. 4. total recalculates: 150 + 12 = 162
  5. All automatically! No manual updates needed.

Expression Syntax

Supported Operations

CategoryOperatorsExample
Arithmetic+ - * / %context.a + context.b
Comparison> < >= <= === !==context.age >= 18
Logical&& || !context.a && context.b
Ternary? :context.x > 10 ? 0 : 5

Math Functions

javascript
// 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 root

String Operations

javascript
// Concatenation
context.firstName + ' ' + context.lastName

// Methods
context.text.toUpperCase()
context.text.toLowerCase()
context.description.substring(0, 100)

Common Patterns

1. Percentage Calculation

json
{
  "discount": {
    "targetPath": "order.discount",
    "expression": "context.order.subtotal * (context.order.discountPercent / 100)",
    "dependencies": ["order.subtotal", "order.discountPercent"]
  }
}

2. Conditional Calculation

json
{
  "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

json
{
  "fullName": {
    "targetPath": "user.fullName",
    "expression": "context.user.firstName + ' ' + context.user.lastName",
    "dependencies": ["user.firstName", "user.lastName"]
  }
}

4. Tiered Calculation

json
{
  "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

json
{
  "expression": "context.price * context.quantity",
  "dependencies": ["price"]  // ❌ Missing quantity!
}

Fix: List ALL fields used in the expression

json
{
  "expression": "context.price * context.quantity",
  "dependencies": ["price", "quantity"]  // ✅ All listed
}

❌ Mistake #2: Forgot "context." Prefix

json
{
  "expression": "price * quantity"  // ❌ Missing context. prefix
}

Fix: Always use context.

json
{
  "expression": "context.price * context.quantity"  // ✅ With context. prefix
}

❌ Mistake #3: Value is Null/Undefined

json
{
  "expression": "context.price * context.quantity"  // ❌ Might fail if null
}

Fix: Provide defaults

json
{
  "expression": "(context.price || 0) * (context.quantity || 1)"  // ✅ With defaults
}

Live Example

🎯 Try It Out

Check out the working example with full source code:

View Computed Fields Demo

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