Ask Anvil

Answers to questions about automating PDFs, e-signatures, Webforms, and other paperwork problems.
PDFs
Categories

Why do zeros and false values disappear from my generated documents, and how do I fix it?

A record has dependents: 0, balanceDue: 0, and hasPriorClaims: false. Every other field on the generated document renders correctly, but those three come out blank. The source data is right, nothing throws, and re-running the job changes nothing.

The cause

The mapping layer is testing truthiness instead of presence. In JavaScript the falsy values include false, 0, -0, 0n, the empty string, null, undefined, and NaN, so record.dependents || '' returns an empty string when the value is a legitimate 0. Python's or behaves the same way: 0, 0.0, False, and '' all fall through to the default. Template engines do it too. Handlebars will not render an {{#if}} block when the argument is false, undefined, null, "", 0, or [], though it offers includeZero=true to opt out.

On a document this matters more than it does inside an app. A blank field reads as "not answered". A zero reads as "none". Falsy coercion quietly converts a factual answer into an omission, and on a tax form, a settlement statement, or a claim questionnaire those are two different statements.

The fix

Test for presence (null or undefined), not for truth, and convert booleans into the text the form actually expects.

const record = { dependents: 0, hasPriorClaims: false, city: 'Austin' }

// Wrong: `||` treats a legitimate 0 or false as "missing"
const bad = {
  dependents: record.dependents || '',
  priorClaims: record.hasPriorClaims || '',
}

// Right: only null and undefined mean "not answered"
const isAnswered = (v) => v !== null && v !== undefined
const toField = (v) => (typeof v === 'boolean' ? (v ? 'Yes' : 'No') : String(v))

const good = {
  dependents: isAnswered(record.dependents) ? toField(record.dependents) : '',
  priorClaims: isAnswered(record.hasPriorClaims) ? toField(record.hasPriorClaims) : '',
}

console.log(bad)  // { dependents: '', priorClaims: '' }
console.log(good) // { dependents: '0', priorClaims: 'No' }

The nullish coalescing operator (record.dependents ?? '') fixes the null and undefined case on its own, but you still need the boolean step, because String(false) is the text "false", which is rarely what belongs on a printed form.

Two things that hide this bug

Data arriving from CSV, a query string, or a loosely typed payload often delivers zero as the string "0", which is truthy in both JavaScript and Python. The mapping passes every test built on that fixture data and only breaks once properly typed values reach it.

A PDF checkbox is not a text field. Writing the string "No" into it does nothing. Map the boolean to the checkbox state instead, for example form.getCheckBox('hasPriorClaims').uncheck() with pdf-lib, and leave the text path for text fields.

Back to All Questions

The fastest way to build software for documents

Anvil Document SDK is a comprehensive toolbox for product teams launching document flows where PDF filling, signing, and complex conditional scenarios are necessary.
Explore Anvil
Anvil Webforms