Automation Blog

Parsing JSON and Numbers in Zapier JavaScript Code Steps

How to safely parse raw JSON strings from webhook payloads and API responses, convert string values to integers and floats, and handle the edge cases that cause silent failures — with copy-paste examples for Zapier Code steps.

ZapierJavaScriptCode Steps

By Troy Tessalone · · 5 minutes

Automation Guide

A practical field guide from Automation Ace.

Parsing JSON and Numbers in Zapier JavaScript Code Steps

Two of the most common data types that need explicit handling in Zapier Code steps are raw JSON strings and numeric values stored as strings. Zapier passes all field values as strings — a number "42.5" isn't the float 42.5 until you convert it, and a JSON payload stored in a field isn't an accessible object until you parse it. This guide covers JSON.parse(), parseInt(), parseFloat(), and the edge cases that cause silent failures when these conversions go wrong.

Parsing Raw JSON: JSON.parse()

When a Zapier trigger or earlier step passes a JSON-formatted string in a field — from a webhook body, a stored Zapier Storage value, or a Code step that used JSON.stringify() — you need JSON.parse() to convert it to a usable JavaScript object:

const raw = inputData.json_string;
// e.g. '{"name":"Jane Smith","email":"jane@example.com","score":95}'

let parsed;
try {
  parsed = JSON.parse(raw);
} catch (e) {
  throw new Error(`Invalid JSON in json_string: ${e.message}`);
}

output = {
  name: parsed.name || '',
  email: parsed.email || '',
  score: String(parsed.score ?? ''),
  raw_type: typeof parsed  // 'object'
};

Always wrap JSON.parse() in a try/catch. If the input string is malformed JSON — truncated, with unescaped quotes, or not JSON at all — JSON.parse() throws a SyntaxError that will fail the Code step with an unhelpful message. The try/catch lets you produce a more descriptive error.

Parsing a Nested JSON Object

const raw = inputData.json_string;
// e.g. '{"contact":{"name":"Jane","address":{"city":"Austin","state":"TX"}},"tags":["vip","enterprise"]}'

let data;
try {
  data = JSON.parse(raw);
} catch (e) {
  throw new Error(`Failed to parse JSON: ${e.message}`);
}

// Safe nested access with optional chaining
const name = data.contact?.name || '';
const city = data.contact?.address?.city || '';
const state = data.contact?.address?.state || '';
const firstTag = data.tags?.[0] || '';
const tagCount = Array.isArray(data.tags) ? data.tags.length : 0;

output = {
  name,
  city,
  state,
  first_tag: firstTag,
  tag_count: String(tagCount),
  tags_joined: Array.isArray(data.tags) ? data.tags.join(', ') : ''
};

Parsing a JSON Array

const raw = inputData.json_array;
// e.g. '[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"},{"id":3,"name":"Carol"}]'

let items;
try {
  items = JSON.parse(raw);
} catch (e) {
  throw new Error(`Invalid JSON array: ${e.message}`);
}

if (!Array.isArray(items)) throw new Error('Expected a JSON array');

const names = items.map(item => item.name || '').filter(Boolean);
const ids = items.map(item => String(item.id || ''));

output = {
  count: String(items.length),
  names: names.join(', '),
  ids: ids.join(','),
  first_name: items[0]?.name || '',
  first_id: String(items[0]?.id || '')
};

parseInt() vs parseFloat(): When to Use Each

Both functions convert a string to a number, but they behave differently:

  • parseInt(string, radix) — converts to an integer, discarding any decimal part. Always pass 10 as the radix to force base-10 parsing.
  • parseFloat(string) — converts to a floating-point number, preserving decimals.
// parseInt examples
parseInt('42', 10)        // 42
parseInt('42.9', 10)      // 42 (decimal truncated, not rounded)
parseInt('42px', 10)      // 42 (stops at first non-numeric character)
parseInt('$42', 10)       // NaN (starts with non-numeric)
parseInt('', 10)          // NaN

// parseFloat examples
parseFloat('42.95')       // 42.95
parseFloat('42')          // 42
parseFloat('$42.95')      // NaN (starts with non-numeric)
parseFloat('42.95 USD')   // 42.95 (stops at space)
parseFloat('')            // NaN

Safe Number Parsing with Fallbacks

Always check for NaN when parsing user-provided or API-sourced strings:

const raw = inputData.amount; // might be "42.50", "$42.50", "", or "N/A"

// Strip non-numeric characters except decimal point and minus sign
const cleaned = raw.replace(/[^0-9.\-]/g, '');
const amount = parseFloat(cleaned);
const amountSafe = isNaN(amount) ? 0 : amount;

// Integer version
const qty = parseInt(inputData.quantity, 10);
const qtySafe = isNaN(qty) ? 0 : qty;

// Format as currency string
const formatted = amountSafe.toFixed(2); // "42.50"

output = {
  amount: String(amountSafe),
  amount_formatted: formatted,
  quantity: String(qtySafe),
  is_valid_amount: !isNaN(amount) ? 'true' : 'false'
};

Number Formatting and Rounding

const value = parseFloat(inputData.value);

// Round to 2 decimal places
const rounded = Math.round(value * 100) / 100;

// toFixed() returns a string with exact decimal places
const fixed2 = value.toFixed(2);  // "42.50"
const fixed0 = value.toFixed(0);  // "43" (rounded)

// Integer division and remainder
const divided = Math.floor(value / 5);
const remainder = value % 5;

// Clamp a value between min and max
const clamped = Math.min(Math.max(value, 0), 100);

output = {
  rounded: String(rounded),
  fixed_2: fixed2,
  fixed_0: fixed0,
  clamped: String(clamped)
};

Converting Output Back to Strings

Zapier Code step output values must be strings or numbers. When outputting computed numeric values, either leave them as numbers or convert explicitly:

// Both are valid output values:
output = {
  count: items.length,           // number — valid
  total: String(sum.toFixed(2)), // string — valid
  label: `Total: $${sum.toFixed(2)}` // string — valid
};

// This would cause issues downstream:
// output = { data: parsedObject }; // objects are NOT valid output values
// output = { items: array };        // arrays are NOT valid output values
// Always JSON.stringify() objects and arrays when outputting them
The two rules that prevent most JSON and number parsing failures: always wrap JSON.parse() in try/catch, and always check isNaN() after parseInt()/parseFloat(). Raw input from Zapier fields can be empty strings, malformed, or in unexpected formats — defensive parsing prevents silent failures where a step succeeds but outputs wrong data.

For string operations on the parsed data, see parsing and transforming strings in Zapier Code steps. For array operations on parsed JSON arrays, see JavaScript array methods in Zapier Code steps. For the full JavaScript environment reference, see JavaScript libraries in Zapier Code steps. For help with a data parsing workflow, talk to Automation Ace.

ZapierJavaScriptCode Steps

Disclaimer: This article may include links to apps, products, or services. Some links may be affiliate links, which means Automation Ace may earn a commission at no extra cost to you.

Build Better Systems

Ready to automate with confidence?

Share your tools, process, and goals. Automation Ace can design the workflow, integration, AI assist, or code bridge that fits your business.

Start a Project