Skip to main content

Overview

The Switch node (conditional branching) allows workflows to take different paths based on values, conditions, or logic. While AutoMFlows doesn’t have a dedicated Switch node type, conditional logic can be implemented using JavaScript Code nodes with conditional execution.
AutoMFlows uses a flow-based approach where conditional branching is achieved through JavaScript Code nodes that set flags, which subsequent nodes can check to determine execution paths.

Implementation Patterns

Basic Conditional Logic

Use JavaScript Code nodes to evaluate conditions and set execution flags:
// In JavaScript Code node
const value = context.getData('someValue');

if (value === 'case1') {
  context.setData('executePath1', true);
  context.setData('executePath2', false);
} else if (value === 'case2') {
  context.setData('executePath1', false);
  context.setData('executePath2', true);
} else {
  context.setData('executePath1', false);
  context.setData('executePath2', false);
}

Value-Based Branching

{
  "type": "javascriptCode",
  "data": {
    "code": "const status = context.getData('orderStatus'); if (status === 'pending') { context.setData('processPending', true); } else if (status === 'complete') { context.setData('processComplete', true); } else { context.setData('processError', true); }"
  }
}

Condition-Based Branching

{
  "type": "javascriptCode",
  "data": {
    "code": "const elementExists = context.getData('isVisible'); if (elementExists) { context.setData('handleVisible', true); } else { context.setData('handleHidden', true); }"
  }
}

Examples

Simple If-Else

Complete Workflow
[
  // Get data
  {
    "type": "elementQuery",
    "data": {
      "action": "getText",
      "selector": ".status",
      "outputVariable": "status"
    }
  },
  // Evaluate condition
  {
    "type": "javascriptCode",
    "data": {
      "code": "const status = context.getData('status'); if (status === 'success') { context.setData('isSuccess', true); console.log('Status is success'); } else { context.setData('isSuccess', false); console.log('Status is not success'); }"
    }
  },
  // Path 1: Success actions
  {
    "type": "action",
    "data": {
      "action": "click",
      "selector": ".success-button",
      "failSilently": true
    }
  },
  // Path 2: Error actions
  {
    "type": "action",
    "data": {
      "action": "click",
      "selector": ".retry-button",
      "failSilently": true
    }
  }
]

Multi-Way Branch

Status Handler
[
  // Check status
  {
    "type": "apiRequest",
    "data": {
      "url": "https://api.example.com/status",
      "contextKey": "statusResponse"
    }
  },
  // Determine path
  {
    "type": "javascriptCode",
    "data": {
      "code": "const status = context.getData('statusResponse').body.status; switch(status) { case 'pending': context.setData('action', 'wait'); break; case 'processing': context.setData('action', 'poll'); break; case 'complete': context.setData('action', 'finish'); break; case 'error': context.setData('action', 'retry'); break; default: context.setData('action', 'unknown'); } console.log('Action:', context.getData('action'));"
    }
  }
]

Nested Conditions

Complex Logic
{
  "type": "javascriptCode",
  "data": {
    "code": "const price = context.getData('price'); const inStock = context.getData('inStock'); const premium = context.getData('isPremium'); if (inStock) { if (premium) { if (price > 100) { context.setData('category', 'premium-expensive'); } else { context.setData('category', 'premium-affordable'); } } else { if (price > 100) { context.setData('category', 'standard-expensive'); } else { context.setData('category', 'standard-affordable'); } } } else { context.setData('category', 'out-of-stock'); }"
  }
}

Range Checks

Age-Based Logic
{
  "type": "javascriptCode",
  "data": {
    "code": "const age = context.getData('userAge'); if (age < 18) { context.setData('ageGroup', 'minor'); context.setData('showAgeRestriction', true); } else if (age < 65) { context.setData('ageGroup', 'adult'); context.setData('showAgeRestriction', false); } else { context.setData('ageGroup', 'senior'); context.setData('showSeniorDiscount', true); }"
  }
}

Boolean Logic

Multiple Conditions
{
  "type": "javascriptCode",
  "data": {
    "code": "const isLoggedIn = context.getData('isLoggedIn'); const hasPermission = context.getData('hasPermission'); const isVerified = context.getData('isVerified'); if (isLoggedIn && hasPermission && isVerified) { context.setData('allowAccess', true); } else if (isLoggedIn && !isVerified) { context.setData('showVerification', true); } else if (isLoggedIn && !hasPermission) { context.setData('showUpgrade', true); } else { context.setData('showLogin', true); }"
  }
}

Common Patterns

API Error Handling

[
  {
    "type": "apiRequest",
    "data": {
      "url": "https://api.example.com/data",
      "contextKey": "apiResponse"
    }
  },
  {
    "type": "javascriptCode",
    "data": {
      "code": "const response = context.getData('apiResponse'); if (response.status >= 200 && response.status < 300) { context.setData('handleSuccess', true); } else if (response.status === 404) { context.setData('handleNotFound', true); } else if (response.status === 401) { context.setData('handleUnauthorized', true); } else if (response.status >= 500) { context.setData('handleServerError', true); } else { context.setData('handleOtherError', true); }"
    }
  }
]

Element State Routing

[
  {
    "type": "elementQuery",
    "data": {
      "action": "isVisible",
      "selector": ".modal",
      "outputVariable": "modalVisible"
    }
  },
  {
    "type": "javascriptCode",
    "data": {
      "code": "const visible = context.getData('modalVisible'); if (visible) { context.setData('closeModal', true); } else { context.setData('openModal', true); }"
    }
  }
]

Data Validation

{
  "type": "javascriptCode",
  "data": {
    "code": "const email = context.getData('userEmail'); const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/; if (!email) { context.setData('validationError', 'Email is required'); } else if (!emailRegex.test(email)) { context.setData('validationError', 'Invalid email format'); } else { context.setData('validationSuccess', true); }"
  }
}

Using failSilently for Branching

Another approach is using failSilently on nodes to continue execution on different paths:
[
  // Try path 1 (fails silently if element not found)
  {
    "type": "action",
    "data": {
      "action": "click",
      "selector": ".option-a",
      "failSilently": true,
      "timeout": 3000
    }
  },
  // Try path 2 (fails silently if element not found)
  {
    "type": "action",
    "data": {
      "action": "click",
      "selector": ".option-b",
      "failSilently": true,
      "timeout": 3000
    }
  }
]

Notes

Conditional logic in AutoMFlows is implemented through JavaScript Code nodes that evaluate conditions and set flags in the context.
Unlike traditional switch/case statements, all nodes in a workflow execute sequentially. Use failSilently or conditional checks within nodes to control execution paths.
For complex conditional logic, consider using the failSilently flag on nodes that should execute only under certain conditions.

Build docs developers (and LLMs) love