📖 2 minutes read
A common bug in Laravel APIs: numeric fields that can be zero display as empty or dash in the frontend because of JavaScript’s falsy value handling. The fix is simple but often overlooked.
The Problem
You have an API that returns configuration with numeric values:
// Backend returns: {"discount_rate": 0}
Frontend code using truthy checks:
// ❌ Displays "—" for zero
{{ config.discount_rate ? config.discount_rate + '%' : '—' }}
// Result: "—" (wrong!)
Why It Fails
In JavaScript, 0 is falsy, so the ternary condition fails and shows the fallback. But 0 might be a perfectly valid value (like “0% discount”).
The Fix
// ✅ Explicit null check
{{ config.discount_rate != null ? config.discount_rate + '%' : '—' }}
// Result: "0%" (correct!)
Backend Considerations
Make sure your Laravel API distinguishes between null (not set) and zero (explicitly set to 0):
// ❌ Bad: Converts 0 to null
public function index()
{
return [
'discount_rate' => $model->discount_rate ?: null
];
}
// ✅ Good: Preserves zero, only null when actually null
public function index()
{
return [
'discount_rate' => $model->discount_rate
];
}
Common Scenarios
- Percentages: 0% is valid (no discount/markup)
- Counts: 0 items is different from unknown
- Ratings: 0 stars might be valid vs unrated
- Prices: $0.00 (free) vs null (price not set)
Pattern for Multiple Fields
// Vue/React pattern
const formatValue = (value) => {
return value != null ? `${value}%` : '—';
};
<template>
<div>Base Rate: {{ formatValue(config.base_rate_markup) }}</div>
<div>Extra Rate: {{ formatValue(config.extra_rate_markup) }}</div>
</template>
Testing Strategy
Always test these edge cases:
- Field is null (not set) → shows fallback
- Field is 0 → shows “0” or “0%”
- Field is positive number → shows number
- Field is negative number (if valid) → shows number
Database Schema Consideration
In migrations, be explicit about nullability:
// If 0 and null have different meanings
$table->decimal('discount_rate', 5, 2)->nullable();
// null = not configured, 0 = explicitly set to zero
// If 0 is the default ("no discount")
$table->decimal('discount_rate', 5, 2)->default(0);
// Always has a value, never null
The Rule of Thumb
- Use
value != nullwhen zero is meaningful - Use
value || defaultwhen zero should fallback (rare for numbers) - Document the distinction in your API responses
This small change prevents countless “the UI shows dash instead of zero” bug reports.
Leave a Reply