Skip to main content

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)
ParameterDescription
valueThe value the helper works on
nameThe helper's name, such as toOptions
optionsThe 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:

GroupHelpers
Dropdown optionstoOptions, findOption
ValuesisBlank, hasValue, get, firstValue, toArray, parseJson, pick, omit
ListsuniqueBy, groupBy, keyBy, sumBy, sortBy
NumberstoNumber, round
Texthumanize, splitList, fillTemplate, escapeRegex, escapeHtml, safeFilename
DatesaddDays, daysBetween, financialYear
UI onlyvalueFromEvent

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:

OptionDefaultMeaning
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
keepRowfalseCopies the row's own fields onto each option
uniquefalseRemoves repeated values
sortfalseSorts by label, ignoring case: true or "asc" for ascending, "desc" for descending
includeAllNoneAdds an "All" option first: a label (its value is "") or { label, value }
skipBlanktrueLeaves 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:

HelperOptions (default)What it does
isBlankNoneReturns true for null, undefined, blank text, and []; required uses the same test
hasValueNoneReturns the opposite of isBlank
getpath (required), fallbackReads a nested value by "a.b.0.c" or ["a", "b"], and returns fallback when it's missing or null
firstValuekeys (required), fallbackReturns the first non-blank value among keys or paths
toArrayNoneTurns a blank into [] and a value into [value], and returns an array unchanged
parseJsonfallbackParses JSON without throwing, and returns fallback for text that isn't JSON
pickkeys (required)Returns a copy with only these keys
omitkeys (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:

HelperOptions (default)What it does
uniqueBykeyRemoves repeats, by the item itself or by a key; 7 and "7" count as different
groupBykey (required)Returns { key: [rows] }, with keys in first-seen order; rows with a missing key group under ""
keyBykey (required)Returns { key: row }; the last row with a key wins
sumBykeyReturns the total of a field; values that aren't numbers count as 0
sortBykey, 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:

HelperOptions (default)What it does
toNumberfallback (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
roundplaces (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:

HelperOptions (default)What it does
humanizeNoneTurns a code into words: "do_received" gives "Do Received", and "BID-START date" gives "Bid Start Date"
splitListseparators ([",", ";"]), unique (true), lower (false)Splits an email or role list, trims each item, and removes blanks and repeats
fillTemplatedata, syntax ("${}"), missing (""), keepMissing (false)Fills ${name}, {{name}}, or {name} placeholders; names can be paths
escapeRegexNoneMakes text safe inside a regular expression
escapeHtmlNoneMakes text safe inside HTML
safeFilenamemaxLength (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")
// "&lt;a href=&quot;x&quot;&gt;Tom&#39;s &amp; co&lt;/a&gt;"

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:

HelperOptions (default)What it does
addDaysdays (required)Adds days; a date gives a date, and a date-time comes back in the UTC wire format
daysBetweento (required), timezone ("Asia/Kolkata")Counts calendar days from the value to to, in timezone
financialYearstartMonth (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"));