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 pass10as 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 wrapJSON.parse()in try/catch, and always checkisNaN()afterparseInt()/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.
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.