Accessing Input Variables

When writing JavaScript in Make.com, all data passed from previous modules is accessible through the input object. Understanding how to properly access and manipulate this data is essential for building effective workflows.

The Input Object

The input object contains all the data passed to your JavaScript module from previous steps in your Make scenario.

Basic Input Access

// Access simple input values
const userName = input.name;
const userEmail = input.email;
const userAge = input.age;

return {
  greeting: `Hello ${userName}`,
  contact: userEmail,
  isAdult: userAge >= 18
};

Input Data Types

1. Simple Values

// String inputs
const message = input.message; // "Hello World"

// Number inputs
const quantity = input.quantity; // 5
const price = input.price; // 29.99

// Boolean inputs
const isActive = input.isActive; // true/false

return {
  processedMessage: message.toUpperCase(),
  totalCost: quantity * price,
  status: isActive ? 'active' : 'inactive'
};

2. Object Inputs

// Accessing nested object properties
const customer = input.customer;
const customerName = customer.name;
const customerAddress = customer.address.street;

// Or use destructuring
const { name, email, address } = input.customer;
const { street, city, zipCode } = address;

return {
  fullName: name,
  contactEmail: email,
  fullAddress: `${street}, ${city} ${zipCode}`
};

3. Array Inputs

// Working with array inputs
const items = input.items;
const itemCount = items.length;
const totalValue = items.reduce((sum, item) => sum + item.price, 0);

// Process each item
const processedItems = items.map(item => ({
  id: item.id,
  name: item.name.toUpperCase(),
  discountedPrice: item.price * 0.9
}));

return {
  itemCount,
  totalValue,
  processedItems
};

Input Validation

Always validate your inputs to prevent errors and ensure data quality.

1. Check for Required Fields

// Validate required inputs
if (!input.email) {
  return { error: "Email is required" };
}

if (!input.userId || typeof input.userId !== 'string') {
  return { error: "Valid userId is required" };
}

// Continue with processing
const processedEmail = input.email.toLowerCase().trim();
return { processedEmail, userId: input.userId };

2. Validate Data Types

// Type validation
if (typeof input.age !== 'number' || input.age < 0) {
  return { error: "Age must be a positive number" };
}

if (!Array.isArray(input.items)) {
  return { error: "Items must be an array" };
}

// Validate array contents
const validItems = input.items.every(item => 
  item.hasOwnProperty('id') && item.hasOwnProperty('name')
);

if (!validItems) {
  return { error: "All items must have id and name properties" };
}

3. Provide Default Values

// Use default values for optional inputs
const limit = input.limit || 10;
const sortOrder = input.sortOrder || 'asc';
const includeInactive = input.includeInactive || false;

// Use nullish coalescing for more precise defaults
const threshold = input.threshold ?? 0; // Only use default if null/undefined
const enableFeature = input.enableFeature ?? true;

return {
  limit,
  sortOrder,
  includeInactive,
  threshold,
  enableFeature
};

Working with Complex Input Structures

1. Nested Objects

// Deep nested access with safety checks
const user = input.user || {};
const profile = user.profile || {};
const preferences = profile.preferences || {};

// Safe property access
const theme = preferences.theme || 'light';
const language = preferences.language || 'en';
const notifications = preferences.notifications?.email || false;

return {
  userTheme: theme,
  userLanguage: language,
  emailNotifications: notifications
};

2. Dynamic Property Access

// Access properties dynamically
const fieldName = input.fieldToProcess; // e.g., "customerName"
const fieldValue = input.data[fieldName];

// Process based on field type
let processedValue;
if (typeof fieldValue === 'string') {
  processedValue = fieldValue.trim().toLowerCase();
} else if (typeof fieldValue === 'number') {
  processedValue = Math.round(fieldValue * 100) / 100;
} else {
  processedValue = fieldValue;
}

return {
  fieldName,
  originalValue: fieldValue,
  processedValue
};

3. Multiple Input Sources

// Combine data from multiple input sources
const userData = input.user || {};
const orderData = input.order || {};
const settingsData = input.settings || {};

// Merge and process
const combinedData = {
  userId: userData.id,
  userName: userData.name,
  orderId: orderData.id,
  orderTotal: orderData.total,
  currency: settingsData.currency || 'USD',
  taxRate: settingsData.taxRate || 0.08
};

// Calculate final values
const taxAmount = combinedData.orderTotal * combinedData.taxRate;
const finalTotal = combinedData.orderTotal + taxAmount;

return {
  ...combinedData,
  taxAmount,
  finalTotal
};

Input Transformation Patterns

1. Data Cleaning

// Clean and normalize input data
const cleanData = {
  email: input.email?.toLowerCase().trim(),
  phone: input.phone?.replace(/\D/g, ''), // Remove non-digits
  name: input.name?.trim().replace(/\s+/g, ' '), // Normalize whitespace
  website: input.website?.toLowerCase().replace(/^https?:\/\//, '')
};

return cleanData;

2. Data Enrichment

// Add calculated fields and metadata
const enrichedUser = {
  ...input.user,
  fullName: `${input.user.firstName} ${input.user.lastName}`,
  initials: `${input.user.firstName[0]}${input.user.lastName[0]}`,
  age: new Date().getFullYear() - new Date(input.user.birthYear).getFullYear(),
  processedAt: new Date().toISOString(),
  source: 'make-workflow'
};

return enrichedUser;

3. Data Restructuring

// Transform flat data into structured format
const flatData = input.csvRow; // e.g., { col1: "John", col2: "Doe", col3: "john@example.com" }

const structuredData = {
  personal: {
    firstName: flatData.col1,
    lastName: flatData.col2,
    fullName: `${flatData.col1} ${flatData.col2}`
  },
  contact: {
    email: flatData.col3,
    emailDomain: flatData.col3.split('@')[1]
  },
  metadata: {
    importedAt: new Date().toISOString(),
    rowNumber: input.rowIndex || 0
  }
};

return structuredData;

Error Handling for Input Processing

1. Graceful Error Handling

try {
  // Attempt to process input
  const result = processComplexInput(input.data);
  return { success: true, result };
} catch (error) {
  return {
    success: false,
    error: error.message,
    inputReceived: typeof input.data,
    timestamp: new Date().toISOString()
  };
}

function processComplexInput(data) {
  if (!data || typeof data !== 'object') {
    throw new Error('Input data must be an object');
  }
  
  // Complex processing logic here
  return data;
}

2. Input Logging for Debugging

// Log input structure for debugging (remove in production)
console.log('Input keys:', Object.keys(input));
console.log('Input types:', Object.keys(input).map(key => `${key}: ${typeof input[key]}`));

// Process the input
const result = {
  processedData: input.data,
  inputMetadata: {
    keyCount: Object.keys(input).length,
    hasRequiredFields: ['id', 'name'].every(field => input.hasOwnProperty(field))
  }
};

return result;

Best Practices for Input Handling

  1. Always validate inputs before processing
  2. Use default values for optional parameters
  3. Handle missing or null values gracefully
  4. Normalize data formats (trim strings, standardize dates, etc.)
  5. Log input structure during development for debugging
  6. Return meaningful error messages when validation fails
  7. Use destructuring for cleaner code when accessing nested properties
  8. Consider input size limits and handle large datasets appropriately

By following these patterns and practices, you'll be able to reliably access and process input variables in your Make.com JavaScript modules.