LukeIf you're building any kind of form that needs area calculations — a room sizing tool, a flooring...
If you're building any kind of form that needs area calculations — a room sizing tool, a flooring estimator, a garden planner — you'll want one small, well-tested utility function rather than scattering length * width across your codebase. Here's a version built to handle real user input, not just clean numbers.
function getArea(length, width) {
return length * width;
}
Works fine until someone passes a string from a form field, a negative number, or leaves a field blank. Then it silently returns NaN or a nonsensical negative area.
function getArea(length, width) {
const l = Number(length);
const w = Number(width);
if (Number.isNaN(l) || Number.isNaN(w)) {
throw new TypeError("Length and width must be valid numbers");
}
if (l <= 0 || w <= 0) {
throw new RangeError("Length and width must be greater than zero");
}
return l * w;
}
This catches the two most common failure modes in a form: empty/non-numeric input and zero-or-negative values (which usually mean a field was left blank and defaulted to 0).
Not every user measures in feet. A more useful version accepts a unit and normalizes internally:
const CONVERSION_TO_FEET = {
feet: 1,
inches: 1 / 12,
meters: 3.28084,
cm: 0.0328084
};
function getAreaInSqFt(length, width, unit = "feet") {
const factor = CONVERSION_TO_FEET[unit];
if (!factor) {
throw new Error(`Unsupported unit: ${unit}`);
}
const l = Number(length) * factor;
const w = Number(width) * factor;
if (Number.isNaN(l) || Number.isNaN(w) || l <= 0 || w <= 0) {
throw new RangeError("Invalid dimensions provided");
}
return l * w;
}
getAreaInSqFt(144, 120, "inches"); // 120
getAreaInSqFt(3.66, 3.05, "meters"); // ~11.16
A function like this is small enough to fully test in a few lines, and worth doing since it's usually feeding a price or budget calculation downstream:
// Using a simple assert-based test, framework-agnostic
function testGetAreaInSqFt() {
console.assert(getAreaInSqFt(12, 10) === 120, "Basic rectangle failed");
console.assert(getAreaInSqFt(144, 120, "inches") === 120, "Inches conversion failed");
try {
getAreaInSqFt(-5, 10);
console.assert(false, "Should have thrown on negative input");
} catch (e) {
console.assert(e instanceof RangeError, "Wrong error type on negative input");
}
try {
getAreaInSqFt("abc", 10);
console.assert(false, "Should have thrown on non-numeric input");
} catch (e) {
console.assert(e instanceof TypeError, "Wrong error type on non-numeric input");
}
console.log("All tests passed");
}
testGetAreaInSqFt();
document.querySelector("#calc-form").addEventListener("submit", (e) => {
e.preventDefault();
const length = document.querySelector("#length").value;
const width = document.querySelector("#width").value;
const unit = document.querySelector("#unit").value;
try {
const area = getAreaInSqFt(length, width, unit);
document.querySelector("#result").textContent = `${area.toFixed(2)} sq ft`;
} catch (err) {
document.querySelector("#result").textContent = `Error: ${err.message}`;
}
});
That's the whole utility — validated, unit-aware, and tested. Drop it into any project needing area math without rebuilding the same edge-case handling every time.
If you want a reference for how this logic looks in a full production tool (multiple room sections, saved history, unit toggles all wired together), squarefootcalc.com is built on the same core function pattern — worth a look for the end-to-end implementation.