Skip to content

9.2 Writing Custom Code ​

You understand what the Custom Code Node can do. Now let's actually build one. This section shows you how to add a Custom Code column and write your first script.


Step-by-Step: Adding a Custom Code Column ​

Step 1: Open Add Column Modal ​

From your taible:

  1. Look for the "+" button in the column headers

    • Usually at the right end of your columns
    • Or next to an existing column
  2. Click the "+" button

    • Add column modal opens
    • Shows available column types

Add Column

Categories:

  • All
  • Data
  • AI & LLM
  • Development
  • Communication

Column Types:

⚡
Code
Run custom code
🔧
Template
Combine text and data

Step 2: Find Custom Code Column Type ​

Method 1: Search

1. Type "code" or "custom" in search box
2. Result shows "Code" column type:
⚡
Code
Run custom code
Select →
3. Click "Code" to continue

Method 2: Browse by Category

1. Click "Development" category:
  • All
  • Data
  • AI & LLM
  • Development ←
  • Communication
2. Find "Code" in the list:
⚡
Code
Run custom code
🔧
Template
Combine text and data
3. Click "Code" to continue

Step 3: Column Configuration Opens ​

After clicking "Code":

Configuration panel appears with settings:

Configure Column

Node Configuration

To access data from other columns, press CTRL + SPACE or start typing the column name.

Configuration Fields Explained ​

Field 1: Column Name ​

Label: "Column Name"

Purpose: Internal identifier for the column

Rules:

  • No spaces (use underscores)
  • Lowercase recommended
  • Alphanumeric and underscores only
  • Must be unique in taible

Examples:

  • ✅ lead_score
  • ✅ custom_validation
  • ✅ calculate_discount
  • ❌ Lead Score (spaces not allowed)
  • ❌ lead-score (hyphens not allowed)

Use in code: Access with the system variable for that column


Field 2: Display Label ​

Label: "Display Label"

Purpose: Human-readable name shown in column header

Rules:

  • Can contain spaces
  • Any characters allowed
  • Displays in column header

Examples:

  • "Lead Score"
  • "Custom Validation"
  • "Calculate Discount"

User sees this in the taible grid


Field 3: Output Type (Optional) ​

Label: "Output type"

Purpose: Specifies the data type returned by your code

Default: any (accepts any type)

When to specify:

  • Type safety
  • Better autocomplete in dependencies
  • Documentation

Simple types:

String
Integer
Boolean
Double

Collection types:

List<String>
List<Map<String, Object>>
Map<String, Object>

Custom types (if defined in your system):

LeadScore
ValidationResult
CompanyData

Leave as any if you're not sure—it will work fine!


Field 4: Code to be executed ​

Label: "Code to be executed"

The main event: This is where you write your Groovy code

Editor features:

  • ✅ Line numbers: Easy reference
  • ✅ Syntax highlighting: Color-coded
  • ✅ Autocomplete: Access column names (via CTRL + SPACE)
  • ✅ Multi-line: Write complex scripts
  • ✅ Current line highlight: Know where you are
  • ✅ Template badges: See column references as green badges
Code Editor Features:
1
2
3
4
5
6
// Calculate total with tax
def quantity = Quantity
def price = Unit Price
def total = quantity * price * 1.1
return total
✓
Line Numbers
See line 1, 2, 3...
✓
Syntax Highlighting
Keywords in blue, numbers in orange
✓
Column References
Green badges show column names
✓
Current Line Highlight
Line 1 is highlighted
✓
Autocomplete
Press CTRL + SPACE
✓
Multi-line
Write complex logic

This is your canvas for custom logic!


Writing Your First Custom Code ​

Example 1: Simple Calculation ​

Goal: Calculate order total from quantity and price

Goal: Calculate order total from quantity and price
1
2
3
4
5
6
7
def quantity = Quantity
def unitPrice = Unit Price
def subtotal = quantity * unitPrice
def tax = subtotal * 0.1
def total = subtotal + tax
return total
Configuration:
• Column name: order_total
• Display label: Order Total
• Output type: Double

How to enter this:

  1. Click in "Code to be executed" editor

  2. Type or paste the code

  3. Set output type: Double (it's a number)

  4. Set column name: order_total

  5. Set display label: "Order Total"

  6. Click "Save"

Result: New column appears, calculates total for each row


Example 2: String Concatenation ​

Goal: Combine first name and last name

Goal: Combine first name and last name
1
2
3
4
def firstName = First Name
def lastName = Last Name
return "${firstName} ${lastName}"

Configuration:

  • Column name: full_name
  • Display label: "Full Name"
  • Output type: String

Tip: This is simple enough that you could use a template instead! But it demonstrates the basics.


Example 3: Conditional Logic ​

Goal: Assign lead tier based on score

Goal: Assign lead tier based on score
1
2
3
4
5
6
7
8
9
10
11
def score = Lead Score
if (score >= 80) {
  return "A - Hot Lead"
} else if (score >= 60) {
  return "B - Warm Lead"
} else if (score >= 40) {
  return "C - Cold Lead"
} else {
  return "D - Unqualified"
}

Configuration:

  • Column name: lead_tier
  • Display label: "Lead Tier"
  • Output type: String

Example 4: Return an Object ​

Goal: Return structured data (multiple fields)

Goal: Return structured data (multiple fields)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def companySize = Company Size
def revenue = Annual Revenue
def tier = 'Small'
def priority = 'Low'
if (companySize > 500 && revenue > 10000000) {
  tier = 'Enterprise'
  priority = 'High'
} else if (companySize > 50) {
  tier = 'Mid-Market'
  priority = 'Medium'
}
return [
  tier: tier,
  priority: priority,
  qualified: priority == 'High',
  category: "${tier} - ${priority}"
]
Result in cell:
{
  "tier": "Enterprise",
  "priority": "High",
  "qualified": true,
  "category": "Enterprise - High"
}

Configuration:

  • Column name: company_classification
  • Display label: "Company Classification"
  • Output type: Map<String, Object>

Result: Cell displays as JSON object

Access nested data in other columns using the autocomplete—just start typing the column name and you'll see nested properties available!


Accessing Column Data ​

How to Reference Columns ​

In the code editor:

  1. Start typing the column name you want to reference

  2. Autocomplete appears showing matching columns

  3. Select the column from the list

  4. A green badge appears showing the column name

1
Start typing the column name:
def quantity = em|
2
Autocomplete shows matching columns:
def quantity = em|
Columns:
Email
Customer email address
Employee Count
Number of employees
3
Select "Email" - a green badge appears:
def email = Email
✓
Done!
The system automatically inserts the correct reference when your code runs.

That's it! The system automatically inserts the correct reference when your code runs.


Using Autocomplete ​

To access column names easily:

  1. In the code editor, press: CTRL + SPACE

  2. Autocomplete popup appears showing available columns

  3. Select column from list

  4. Green badge appears showing the column reference

Press CTRL + SPACE to see all available columns:
Available Columns:
Email
First Name
Last Name
Company Size
Annual Revenue
Lead Score
Unit Price
Quantity

Tip: You can also just start typing a column name and the autocomplete will filter to matching columns!


Safe Navigation (Avoiding Null Errors) ​

Problem: Column might be empty or null

Bad code (will crash if empty):

groovy
def email = [Email Column]
def domain = email.split('@')[1] // CRASH if email is null!

Good code (safe navigation):

groovy
def email = [Email Column]
def domain = email?.split('@')?.getAt(1) // Returns null if email is null

// Or with default value
def emailValue = [Email Column] ?: 'no-email@example.com'
❌ Bad (will crash):
def email = [Email]
def domain = email.split('@')[1]
// CRASH if email is null!
✅ Good (safe):
def email = [Email]
def domain = email?.split('@')?.getAt(1)
// Returns null if email is null

Safe navigation operator: ?.

  • If left side is null, entire expression returns null
  • No crash!

Elvis operator: ?:

  • If left side is null, use right side (default value)

Accessing Nested Data ​

When column contains object:

Column Enrichment Result contains: { name: "Acme Corp", employees: 500, industry: "Technology" }
def enrichment = Enrichment Result
// Access nested properties
def companyName = enrichment.name
def employees = enrichment.employees
def industry = enrichment.industry
return "${companyName}, Size: ${employees}"

Accessing Array Data ​

When column contains list:

Column Contacts contains array of objects
def contacts = Contacts
// Get first item
def firstContact = contacts[0]
// Count items
def count = contacts.size()
// Filter items
def active = contacts.findAll { it.status == 'active' }

Available Built-in Variables ​

objectMapper (JSON Operations) ​

Purpose: Parse and create JSON

Parse JSON string:
def jsonString = '{"name": "John", "age": 30}'
def parsed = objectMapper.readValue(jsonString, Map)
def name = parsed.name // "John"
Create JSON string:
def myObject = [name: "John", age: 30]
def jsonString = objectMapper.writeValueAsString(myObject)
// Result: '{"name":"John","age":30}'

Column References (Data) ​

Purpose: Access all column data in current row

Usage: Use autocomplete (CTRL + SPACE) to insert column references

Always available in your code


executeColumn (Advanced) ​

Purpose: Execute another column programmatically

// Execute another column programmatically
def result = executeColumn('enrich_company')
if (result?.data) {
  def enrichedData = result.data
  return enrichedData
} else {
  return null
}
⚠️ Caution: Can create circular dependencies—be careful!

When to use:

  • Conditional column execution
  • Dynamic workflows
  • Complex dependencies

Caution: Can create circular dependencies—be careful!


Testing Your Custom Code ​

Step 1: Save Configuration ​

  1. Click "Save" button at bottom of configuration panel

  2. Column is created in your taible

  3. Configuration closes


Step 2: Add Test Row ​

To test your code:

  1. Add a new row at the bottom of taible

    • Click "Add Row" or use row menu
  2. Fill in dependency columns

    • Enter data for columns your code reads
    • Example: If code reads quantity and price, enter values
  3. Custom code column executes automatically

    • State: Queued → Running → Completed
    • Or Error if there's a problem
Cell Execution States:
Queued
Waiting to execute
Running
Currently executing
Completed
Success!
Code executed successfully
Error
Failed
Click to see error details

Step 3: Check Result ​

If successful (Completed, green badge):

  • Cell shows your returned value
  • Click cell to see full data

If failed (Error, red badge with zap icon):

  • Click cell to see error
  • Error sidebar shows detailed information
✅ If Successful:
Completed$245.50
• Cell shows your returned value
• Click cell to see full data
❌ If Failed:
Error
• Click error button to see details
• Shows error message and stack trace

Step 4: Fix Errors ​

Common errors:

ErrorCauseFix
Cannot get property 'field' on nullAccessed null valueUse safe navigation ?.
No such property: columnNameTypo in column nameCheck spelling in autocomplete
Cannot cast X to YType mismatchCheck data types, use conversions

How to fix:

  1. Click column header → settings icon

  2. Edit code in configuration

  3. Save changes

  4. Select failed cells → Right-click → "Recalculate cells"

  5. Cells re-execute with updated code

1
Click column header → settings icon
2
Edit code in configuration
3
Save changes
4
Select failed cells → Right-click → "Recalculate cells"
✓
Cells re-execute with updated code

Step 5: Test with Multiple Rows ​

Once working with one row:

  1. Add more test rows with various data

    • Test edge cases
    • Test empty values
    • Test boundary conditions
  2. Verify all execute successfully

  3. Check results make sense

If all good: Your custom code is ready! ✓


Code Editor Tips ​

Tip 1: Use Comments ​

Document your code:

groovy
// Calculate lead score based on company size and industry
def companySize = [Company Size]

// Award points for company size
def score = 0
if (companySize > 1000) {
  score += 30 // Large company
} else if (companySize > 100) {
  score += 20 // Mid-size company
}

return score

Why: Makes code maintainable


Tip 2: Format for Readability ​

Bad (hard to read):

groovy
def score=0
if([Company Size]>1000){score+=30}else if([Company Size]>100){score+=20}
return score

Good (easy to read):

groovy
def score = 0
def companySize = [Company Size]

if (companySize > 1000) {
  score += 30
} else if (companySize > 100) {
  score += 20
}

return score

Tip 3: Use Variables ​

Instead of repeating:

groovy
if ([Company Size] > 1000) {
  // ... later ...
  def size = [Company Size]
}

Extract to variable:

groovy
def companySize = [Company Size]

if (companySize > 1000) {
  // Use companySize
}

Benefits: Shorter, clearer, less error-prone


Tip 4: Return Early ​

Complex nested conditions (hard to follow):

groovy
def score = 0
if ([Email]) {
  if ([Company Size]) {
    if ([Industry]) {
      // Calculate score
      score = complexCalculation()
    }
  }
}
return score

Return early (easier to understand):

groovy
// Validate required fields
def email = [Email]
if (!email) return 0

def companySize = [Company Size]
if (!companySize) return 0

def industry = [Industry]
if (!industry) return 0

// All required fields present, calculate score
return complexCalculation()

Tip 5: Test Incrementally ​

Don't write all at once:

  1. Start simple: return "Hello"
  2. Add data access: return [Email]
  3. Add logic piece by piece
  4. Test after each addition

If it breaks: You know which piece caused it


Modifying Existing Custom Code ​

To Edit Custom Code Column ​

  1. Click column header (column you want to edit)

  2. Click settings icon (⚙️) or three-dot menu (⋮)

  3. Select "Edit Column"

  4. Configuration panel opens with current code

  5. Modify code in editor

  6. Click "Save"

  7. Existing cells keep old values (won't auto-recalculate)

  8. To update cells with new code:

    • Select cells
    • Right-click → "Recalculate cells"
    • Cells re-execute with new code
To Edit Column:
1.
Click column header
2.
Click settings icon ⚙️
3.
Modify code
4.
Click "Save"
To Update Cells:
1.
Select cells to update
2.
Right-click
3.
Choose "Recalculate cells"
✓
Cells execute with new code

Version Control Tip ​

Before major changes:

  1. Duplicate the column (create backup)

    • Same code, different name
  2. Test changes in new column

  3. If works: Delete old column

  4. If breaks: Revert to backup

Prevents data loss during experimentation


Common Patterns ​

Pattern 1: Data Validation ​

Pattern: Data Validation
// Validate email format
def email = Email
if (!email) {
  return [valid: false, error: 'Email is required']
}
if (!email.contains('@') || !email.contains('.')) {
  return [valid: false, error: 'Invalid email format']
}
return [valid: true, email: email]

Pattern 2: Fallback Values ​

Pattern: Fallback Values
// Use enriched if available, else manual entry
def enrichedName = Enriched Company
def manualName = Manual Company
return enrichedName ?: manualName ?: 'Unknown Company'

Pattern 3: Scoring/Classification ​

Pattern: Scoring/Classification
// Multi-factor scoring
def score = 0
// Factor 1: Company size
def size = Company Size ?: 0
score += size > 1000 ? 30 : size > 100 ? 20 : 10
// Factor 2: Industry
def industry = Industry
if (industry in ['Technology', 'Finance']) {
  score += 25
}
return [score: score, grade: score > 70 ? 'A' : 'B']

Pattern 4: Data Transformation ​

Pattern: Data Transformation
// Transform raw data to standardized format
def rawPhone = Phone
if (!rawPhone) return null
// Remove non-numeric
def cleaned = rawPhone.replaceAll(/[^\d]/, '')
// Format
if (cleaned.length() == 10) {
  return "+1 (${cleaned[0..2]}) ${cleaned[3..5]}-${cleaned[6..9]}"
} else {
  return cleaned
}

Summary: Writing Custom Code ​

You now know how to write custom code:

✅ Add Custom Code column:

  • Click "+" → Search "code" → Configure

✅ Configuration fields:

  • Column name (internal identifier)
  • Display label (shown in header)
  • Output type (optional, for type safety)
  • Code editor (where magic happens)

✅ Write code:

  • Use autocomplete to insert column references
  • Use objectMapper for JSON
  • Use executeColumn for dynamic execution
  • Return value (simple or complex)

✅ Test code:

  • Add test row
  • Check result
  • Fix errors
  • Test edge cases

✅ Code editor tips:

  • Use comments
  • Format for readability
  • Use variables
  • Return early
  • Test incrementally

✅ Common patterns:

  • Data validation
  • Fallback values
  • Scoring/classification
  • Data transformation

Next Steps ​

Now that you can write custom code, Section 9.3 will show you:

  • Real-world custom code examples
  • Lead scoring algorithms
  • Complex data transformations
  • API integration patterns
  • Advanced techniques

Let's see custom code in action! 🚀

Built with VitePress