The great majority of circulating currencies are decimal. If you're working with those, the Dinero.js formatting utility should cover most of your use cases.
However, you might also work with non-decimal currencies. Typical use cases are ancient currencies such as the ancient Greek drachma, or fictional currencies like the wizarding currencies in the Harry Potter universe. If you're building a numismatic site or a game with its own currency, you might have advanced formatting needs.
Out of the box, you can format any non-decimal Dinero object using the exposed units
property.
import { dinero, toFormat, toSnapshot } from 'dinero.js';
import pluralize from 'pluralize';
// ...
function transformer({ dineroObject }) {
const { units, currency } = toSnapshot(dineroObject);
const amounts = [
{ amount: units[0], label: 'drachma' },
{ amount: units[1], label: 'obol' },
];
return amounts
.filter(({ amount }) => amount > 0)
.map(({ amount, label }) => `${amount} ${pluralize(label, amount)}`)
.join(', ');
}
toFormat(d, transformer); // "1 drachma, 3 obols"
Copy linkHandling currencies with multiple subdivisions
While most circulating currencies have a single minor currency unit, many ancient currencies have multiple subdivisions. That's the case for most pre-decimalization European currencies such as the livre tournois in the French Old Regime or the pound sterling in Great Britain before 1971. That's also the case of some fictional currencies.
When working with such currencies, you can specify each subdivision with an array.
For example, let's say you're building a Candy Crush clone where users can buy bonuses with an in-game currency: donuts, cookies, and lollipops. In your game, a donut equals 30 cookies, and a cookie equals 16 lollipops. If a bonus costs 720 lollipops, you probably want to format it either into "720 lollipops" or "1 donut and 15 cookies".
import { dinero, toFormat, toSnapshot } from 'dinero.js';
const POP = {
code: 'POP',
base: [30, 16],
exponent: 1,
};
function transformer({ units }) {
const amounts = [
{ amount: units[0], label: '🍩' },
{ amount: units[1], label: '🍪' },
{ amount: units[2], label: '🍭' },
];
return amounts
.filter(({ amount }) => amount > 0)
.map(({ amount, label }) => `${amount} ${label}`)
.join(' and ');
}
const d = dinero({ amount: 720, currency: POP });
toFormat(d, transformer); // "1 🍩 and 15 🍪"
toFormat(d, ({ dineroObject }) => `${toSnapshot(dineroObject).amount} 🍭`); // "720 🍭"