Using JSON for Complex Data

JSON (JavaScript Object Notation) is the primary format for handling complex data structures in Make.com workflows. Understanding how to work with JSON effectively is crucial for building sophisticated automation scenarios.

Understanding JSON in Make.com Context

What is JSON?

JSON is a lightweight, text-based data interchange format that's easy for humans to read and write, and easy for machines to parse and generate.

// Example JSON structure
const jsonData = {
  "user": {
    "id": 123,
    "name": "John Doe",
    "email": "john@example.com",
    "preferences": {
      "theme": "dark",
      "notifications": true
    }
  },
  "orders": [
    {
      "id": "order-001",
      "total": 99.99,
      "items": ["item1", "item2"]
    }
  ]
};

Basic JSON input access

For enhanced flexibility in processing input data, you can directly retrieve the value from the input field using the JavaScript variable 'Input'. If your scenario requires passing multiple values, our service enables the creation of a JSON object in the input field. This method provides a structured and efficient way to process complex data.

Input-Field

{ "json": { "firstName": "John Doe" } }

JS-Code-Field

return input.json.firstName;

Output-Field

{ output: "John Doe" }



You have to make sure that your input is a valid JSON String and not an object as you write it in JavaScript for example.

Make.com Custom JavaScript JSON Parameter Example
Make.com Custom JavaScript JSON Parameter Example

Make.com Custom JavaScript JSON Parameter Example
Make.com Custom JavaScript JSON Parameter Example

Make.com Custom JavaScript JSON Parameter Example
Make.com Custom JavaScript JSON Parameter Example

Make.com Custom JavaScript JSON Parameter Example
Make.com Custom JavaScript JSON Parameter Example

Working with JSON Input

1. Parsing JSON Strings

// If input comes as a JSON string, parse it first
let data;
try {
  data = JSON.parse(input.jsonString);
} catch (error) {
  return { error: "Invalid JSON format", details: error.message };
}

// Now work with the parsed data
const userId = data.user.id;
const userName = data.user.name;

return {
  userId,
  userName,
  orderCount: data.orders.length
};

2. Handling Already Parsed JSON

// If input is already a JavaScript object (most common in Make)
const userData = input.user;
const orders = input.orders || [];

// Process the data
const processedUser = {
  id: userData.id,
  displayName: userData.name.toUpperCase(),
  email: userData.email.toLowerCase(),
  hasOrders: orders.length > 0
};

return processedUser;

Creating JSON Structures

1. Building Complex Objects

// Create nested JSON structure
const customerProfile = {
  personal: {
    id: input.customerId,
    name: {
      first: input.firstName,
      last: input.lastName,
      full: `${input.firstName} ${input.lastName}`
    },
    contact: {
      email: input.email,
      phone: input.phone,
      address: {
        street: input.street,
        city: input.city,
        country: input.country,
        postalCode: input.postalCode
      }
    }
  },
  preferences: {
    marketing: input.marketingOptIn || false,
    newsletter: input.newsletterOptIn || false,
    language: input.language || 'en'
  },
  metadata: {
    createdAt: new Date().toISOString(),
    source: 'make-automation',
    version: '1.0'
  }
};

return customerProfile;

2. Dynamic JSON Construction

// Build JSON dynamically based on conditions
const result = {
  id: input.id,
  type: input.type
};

// Add properties conditionally
if (input.name) {
  result.name = input.name;
}

if (input.email) {
  result.contact = {
    email: input.email,
    verified: input.emailVerified || false
  };
}

if (input.tags && Array.isArray(input.tags)) {
  result.tags = input.tags.filter(tag => tag.trim().length > 0);
}

// Add computed properties
result.slug = input.name ? input.name.toLowerCase().replace(/\s+/g, '-') : null;
result.updatedAt = new Date().toISOString();

return result;

JSON Array Processing

1. Transforming Arrays

// Process array of objects
const products = input.products || [];

const processedProducts = products.map(product => ({
  id: product.id,
  name: product.name,
  price: {
    original: product.price,
    formatted: `$${product.price.toFixed(2)}`,
    currency: 'USD'
  },
  category: {
    id: product.categoryId,
    name: product.categoryName,
    slug: product.categoryName.toLowerCase().replace(/\s+/g, '-')
  },
  availability: {
    inStock: product.stock > 0,
    quantity: product.stock,
    status: product.stock > 0 ? 'available' : 'out-of-stock'
  }
}));

return {
  products: processedProducts,
  totalCount: processedProducts.length,
  inStockCount: processedProducts.filter(p => p.availability.inStock).length
};

2. Grouping and Aggregating

// Group products by category
const products = input.products || [];

const groupedByCategory = products.reduce((groups, product) => {
  const category = product.category || 'uncategorized';
  
  if (!groups[category]) {
    groups[category] = {
      name: category,
      products: [],
      totalValue: 0,
      count: 0
    };
  }
  
  groups[category].products.push(product);
  groups[category].totalValue += product.price || 0;
  groups[category].count += 1;
  
  return groups;
}, {});

// Convert to array format
const categorySummary = Object.values(groupedByCategory).map(category => ({
  ...category,
  averagePrice: category.totalValue / category.count
}));

return {
  categories: categorySummary,
  totalCategories: categorySummary.length,
  grandTotal: categorySummary.reduce((sum, cat) => sum + cat.totalValue, 0)
};

JSON Validation and Error Handling

1. Schema Validation

// Define expected structure
const requiredFields = ['id', 'name', 'email'];
const optionalFields = ['phone', 'address', 'preferences'];

// Validate input structure
const missingFields = requiredFields.filter(field => !input.hasOwnProperty(field));

if (missingFields.length > 0) {
  return {
    error: "Missing required fields",
    missingFields,
    receivedFields: Object.keys(input)
  };
}

// Validate data types
const validationErrors = [];

if (typeof input.id !== 'string' && typeof input.id !== 'number') {
  validationErrors.push('ID must be string or number');
}

if (typeof input.name !== 'string' || input.name.trim().length === 0) {
  validationErrors.push('Name must be a non-empty string');
}

if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.email)) {
  validationErrors.push('Email must be valid format');
}

if (validationErrors.length > 0) {
  return {
    error: "Validation failed",
    validationErrors
  };
}

// Process valid data
return {
  success: true,
  processedData: {
    id: input.id,
    name: input.name.trim(),
    email: input.email.toLowerCase()
  }
};

2. Safe Property Access

// Use optional chaining and nullish coalescing for safe access
const user = input.user || {};
const address = user.address || {};

const processedAddress = {
  street: address.street ?? 'Not provided',
  city: address.city ?? 'Not provided',
  country: address.country ?? 'Unknown',
  postalCode: address.postalCode ?? null,
  coordinates: {
    lat: address.coordinates?.lat ?? null,
    lng: address.coordinates?.lng ?? null
  }
};

// Check if address is complete
const isCompleteAddress = processedAddress.street !== 'Not provided' && 
                         processedAddress.city !== 'Not provided' && 
                         processedAddress.country !== 'Unknown';

return {
  address: processedAddress,
  isComplete: isCompleteAddress,
  hasCoordinates: processedAddress.coordinates.lat !== null
};

JSON Transformation Patterns

1. Flattening Nested JSON

// Flatten nested structure for easier processing
function flattenObject(obj, prefix = '') {
  const flattened = {};
  
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      const newKey = prefix ? `${prefix}.${key}` : key;
      
      if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
        Object.assign(flattened, flattenObject(obj[key], newKey));
      } else {
        flattened[newKey] = obj[key];
      }
    }
  }
  
  return flattened;
}

const nestedData = input.complexObject;
const flattenedData = flattenObject(nestedData);

return {
  original: nestedData,
  flattened: flattenedData,
  fieldCount: Object.keys(flattenedData).length
};

2. Converting Between Formats

// Convert array of objects to different structures
const records = input.records || [];

// Convert to key-value pairs
const keyValuePairs = records.map(record => ({
  key: record.id,
  value: record.name,
  metadata: {
    type: record.type,
    active: record.active
  }
}));

// Convert to lookup object
const lookupObject = records.reduce((lookup, record) => {
  lookup[record.id] = {
    name: record.name,
    type: record.type,
    active: record.active
  };
  return lookup;
}, {});

// Convert to CSV-like structure
const csvHeaders = ['id', 'name', 'type', 'active'];
const csvRows = records.map(record => 
  csvHeaders.map(header => record[header] || '')
);

return {
  keyValuePairs,
  lookupObject,
  csvData: {
    headers: csvHeaders,
    rows: csvRows
  }
};

Working with Large JSON Data

1. Chunking Large Arrays

// Process large arrays in chunks
const largeArray = input.items || [];
const chunkSize = 100;

function chunkArray(array, size) {
  const chunks = [];
  for (let i = 0; i < array.length; i += size) {
    chunks.push(array.slice(i, i + size));
  }
  return chunks;
}

const chunks = chunkArray(largeArray, chunkSize);
const processedChunks = chunks.map((chunk, index) => ({
  chunkIndex: index,
  itemCount: chunk.length,
  processedItems: chunk.map(item => ({
    id: item.id,
    processed: true,
    processedAt: new Date().toISOString()
  }))
}));

return {
  totalItems: largeArray.length,
  chunkCount: chunks.length,
  chunkSize,
  chunks: processedChunks
};

2. Memory-Efficient Processing

// Process data without creating large intermediate objects
const items = input.items || [];
let totalValue = 0;
let processedCount = 0;
const summary = {
  categories: {},
  priceRanges: {
    low: 0,    // 0-50
    medium: 0, // 51-200
    high: 0    // 201+
  }
};

// Process items one by one
for (const item of items) {
  if (item.price && typeof item.price === 'number') {
    totalValue += item.price;
    processedCount++;
    
    // Update category count
    const category = item.category || 'uncategorized';
    summary.categories[category] = (summary.categories[category] || 0) + 1;
    
    // Update price range count
    if (item.price <= 50) {
      summary.priceRanges.low++;
    } else if (item.price <= 200) {
      summary.priceRanges.medium++;
    } else {
      summary.priceRanges.high++;
    }
  }
}

return {
  summary,
  totalValue,
  processedCount,
  averagePrice: processedCount > 0 ? totalValue / processedCount : 0
};

Best Practices for JSON in Make.com

  1. Always validate JSON structure before processing
  2. Use try-catch blocks when parsing JSON strings
  3. Provide meaningful error messages for invalid data
  4. Use consistent property naming (camelCase recommended)
  5. Include metadata (timestamps, source, version) in your JSON
  6. Handle null and undefined values gracefully
  7. Consider data size limits when creating large JSON objects
  8. Use optional chaining (?.) for safe property access
  9. Normalize data formats (dates, emails, phone numbers)
  10. Document your JSON structure for team collaboration

Working effectively with JSON in Make.com enables you to build powerful, data-driven automation workflows that can handle complex business logic and data transformations.


title: JSON Parameter Handling description: Learn how to effectively manage JSON parameters with custom JavaScript for PDF conversions on Make.com. slug: json-parameter