helpers()
helpers runs one of 27 small utilities that services often write for themselves, with the same answers in JavaScript and Python.
helpers(value, name, options)
| Parameter | Description |
|---|---|
value | The value the helper works on |
name | The helper's name, such as toOptions |
options | The helper's options; required when the helper has a required option |
Returns
Each helper returns its own result, described in its table row.
Throws
helpers throws an error for an unknown helper or option name, or a missing required option.
Helper groups
The helpers fall into these groups:
| Group | Helpers |
|---|---|
| Dropdown options | toOptions, findOption |
| Values | isBlank, hasValue, get, firstValue, toArray, parseJson, pick, omit |
| Lists | uniqueBy, groupBy, keyBy, sumBy, sortBy |
| Numbers | toNumber, round |
| Text | humanize, splitList, fillTemplate, escapeRegex, escapeHtml, safeFilename |
| Dates | addDays, daysBetween, financialYear |
| UI only | valueFromEvent |
Dropdown options
These helpers build and search the [{ label, value }] lists that select and dropdown components take.
toOptions
toOptions turns rows, plain values, or an object map into [{ label, value }].
const rows = [{ id: 7, name: "Acme" }, { id: 8, name: "Beta" }];
helpers(rows, "toOptions", { label: "name", value: "id" })
// [{ label: "Acme", value: 7 }, { label: "Beta", value: 8 }]
helpers(rows, "toOptions", { label: ["code", "email"], value: "email" }) // label "FF01 - ops@example.com"
helpers(["Air", "Sea"], "toOptions") // [{ label: "Air", value: "Air" }, { label: "Sea", value: "Sea" }]
helpers({ INR: "Rupee" }, "toOptions") // [{ label: "Rupee", value: "INR" }]
helpers(rows, "toOptions", { label: (r) => `${r.first} ${r.last}`, value: "id" })
helpers(rows, "toOptions", { label: "name", value: "id", unique: true, sort: true, keepRow: true, includeAll: "All" })
toOptions takes these options:
| Option | Default | Meaning |
|---|---|---|
label | "label" | A key, several keys joined with separator (blanks skipped), or a function (row) => label |
value | "value" | A key or a function (row) => value |
separator | " - " | The text that joins several label keys |
keepRow | false | Copies the row's own fields onto each option |
unique | false | Removes repeated values |
sort | false | Sorts by label, ignoring case: true or "asc" for ascending, "desc" for descending |
includeAll | None | Adds an "All" option first: a label (its value is "") or { label, value } |
skipBlank | true | Leaves out rows whose value is blank |
findOption
findOption returns the option whose value matches, or null.
The values 7 and "7" match, because a select often holds its value as text.
const options = [{ label: "Acme", value: 7 }, { label: "Beta", value: 8 }];
helpers("7", "findOption", { options }) // { label: "Acme", value: 7 }
helpers(9, "findOption", { options }) // null
findOption takes one option, options, which is required and holds the options to search.
Values
These helpers read and test single values and objects:
| Helper | Options (default) | What it does |
|---|---|---|
isBlank | None | Returns true for null, undefined, blank text, and []; required uses the same test |
hasValue | None | Returns the opposite of isBlank |
get | path (required), fallback | Reads a nested value by "a.b.0.c" or ["a", "b"], and returns fallback when it's missing or null |
firstValue | keys (required), fallback | Returns the first non-blank value among keys or paths |
toArray | None | Turns a blank into [] and a value into [value], and returns an array unchanged |
parseJson | fallback | Parses JSON without throwing, and returns fallback for text that isn't JSON |
pick | keys (required) | Returns a copy with only these keys |
omit | keys (required) | Returns a copy without these keys |
helpers({ a: { b: [{ c: 5 }] } }, "get", { path: "a.b.0.c" }) // 5
helpers({ a: "", b: null, c: "x" }, "firstValue", { keys: ["a", "b", "c"] }) // "x"
helpers({ contact: { email: "ops@example.com" } }, "firstValue", { keys: ["email", "contact.email"] }) // "ops@example.com"
helpers('["exim","admin"]', "parseJson") // ["exim", "admin"]
helpers("exim,admin", "parseJson") // null
Lists
These helpers work on arrays of values or rows:
| Helper | Options (default) | What it does |
|---|---|---|
uniqueBy | key | Removes repeats, by the item itself or by a key; 7 and "7" count as different |
groupBy | key (required) | Returns { key: [rows] }, with keys in first-seen order; rows with a missing key group under "" |
keyBy | key (required) | Returns { key: row }; the last row with a key wins |
sumBy | key | Returns the total of a field; values that aren't numbers count as 0 |
sortBy | key, order ("asc") | Sorts numbers as numbers and text ignoring case, puts blanks last in both orders, and keeps equal items in their order |
The key option is a key, a dotted path such as "q.amt", or a function (row) => key.
const rows = [{ id: 7, n: "a" }, { id: 8, n: "b" }, { id: 7, n: "c" }];
helpers(rows, "uniqueBy", { key: "id" }) // [{ id: 7, n: "a" }, { id: 8, n: "b" }]
helpers(rows, "groupBy", { key: "id" }) // { "7": [{ id: 7, n: "a" }, { id: 7, n: "c" }], "8": [{ id: 8, n: "b" }] }
helpers([{ a: "1,000" }, { a: 2.5 }, { a: "x" }, {}], "sumBy", { key: "a" }) // 1002.5
helpers([{ n: "b" }, { n: 10 }, { n: "" }, { n: "A" }, { n: 2 }], "sortBy", { key: "n" })
// [{ n: 2 }, { n: 10 }, { n: "A" }, { n: "b" }, { n: "" }]
Numbers
These helpers read and round numbers:
| Helper | Options (default) | What it does |
|---|---|---|
toNumber | fallback (0) | Reads a number from text, for example " 1,250.50 " gives 1250.5 and ".5" gives 0.5; other text, true, and false give fallback |
round | places (2) | Rounds halves away from zero, using the decimal value you see: 1.005 gives 1.01, -1.005 gives -1.01, and 2.5 with zero places gives 3 |
round avoids two common surprises: Math.round(1.005 * 100) / 100 gives 1 in JavaScript, and round(2.5) gives 2 in Python.
Text
These helpers clean and build text:
| Helper | Options (default) | What it does |
|---|---|---|
humanize | None | Turns a code into words: "do_received" gives "Do Received", and "BID-START date" gives "Bid Start Date" |
splitList | separators ([",", ";"]), unique (true), lower (false) | Splits an email or role list, trims each item, and removes blanks and repeats |
fillTemplate | data, syntax ("${}"), missing (""), keepMissing (false) | Fills ${name}, {{name}}, or {name} placeholders; names can be paths |
escapeRegex | None | Makes text safe inside a regular expression |
escapeHtml | None | Makes text safe inside HTML |
safeFilename | maxLength (120), replacement ("_") | Keeps only letters, digits, ., _, and -, and keeps the extension |
helpers("a@example.com; b@example.com, a@example.com", "splitList") // ["a@example.com", "b@example.com"]
helpers("A@EXAMPLE.com, a@example.com", "splitList", { lower: true }) // ["a@example.com"]
helpers("RFQ ${rfq_id} for ${vendor.name}", "fillTemplate", { data: { rfq_id: 12, vendor: { name: "Acme" } } })
// "RFQ 12 for Acme"
helpers("Hello {{ name }}", "fillTemplate", { syntax: "{{}}", data: { name: "Asha" } }) // "Hello Asha"
helpers("Port {port}", "fillTemplate", { syntax: "{}", missing: "-", data: {} }) // "Port -"
helpers(`<a href="x">Tom's & co</a>`, "escapeHtml")
// "<a href="x">Tom's & co</a>"
helpers("Invoice #12 (final).pdf", "safeFilename") // "Invoice_12_final_.pdf"
helpers("../etc/passwd", "safeFilename") // "etc_passwd"
helpers("", "safeFilename") // "file"
Dates
These helpers do date arithmetic in calendar days:
| Helper | Options (default) | What it does |
|---|---|---|
addDays | days (required) | Adds days; a date gives a date, and a date-time comes back in the UTC wire format |
daysBetween | to (required), timezone ("Asia/Kolkata") | Counts calendar days from the value to to, in timezone |
financialYear | startMonth (4), timezone ("Asia/Kolkata") | Returns the financial year that a date falls in, April to March by default |
helpers("2026-12-25", "addDays", { days: 10 }) // "2027-01-04"
helpers("2026-10-01", "daysBetween", { to: "2026-10-07" }) // 6
helpers("2026-10-07", "daysBetween", { to: "2026-10-01" }) // -6
helpers("2026-10-06 20:00:00", "daysBetween", { to: "2026-10-07" })
// 0, because 20:00 UTC on the 6th is already the 7th in IST
helpers("2027-01-15", "financialYear")
// { startYear: 2026, endYear: 2027, start: "2026-04-01", end: "2027-03-31", label: "2026-27", code: "2627" }
In Python, financialYear returns its keys in snake_case, such as start_year and end_year.
UI only
This helper is available in JavaScript only.
valueFromEvent
valueFromEvent returns the value from an onChange event, a select's option ({ value }), or a plain value, so one handler works for any input.
For a checkbox, it returns true or false.
For null and undefined, it returns "".
const onChange = (e) => setValue(helpers(e, "valueFromEvent"));