format.js

/* eslint-disable prefer-template */
/**
 * Formatting data
 * @module
 * @since  0.0.32
 */

/**
 * Format to use commas and decimal places
 * @param {number} number
 * @param {number} decimal_places
 * @returns {string}
 */
const numberWithCommas = (number, decimal_places = 2) => number.toLocaleString('en-US', {
    minimumFractionDigits: decimal_places,
    maximumFractionDigits: decimal_places,
});

/**
 * For formatting values with data types
 * @param value Value passed in to change
 * @param {string} type Data type e.g string, number
 * @param {boolean} is_display to determine whether return a string and will handle decimal
 * from being rounded
 * @param {number} decimal_places decimal places to round to
 * @returns {number | string}
 */
const format = (
    value,
    type,
    is_display = true,
    decimal_places = 0,
) => {
    // handle missing values
    if (
        typeof value === 'undefined'
        || (typeof value === 'string' && !value.length)
    ) {
        return '-';
    }

    // handling decimal places by doing 10 to the power of decimal places
    const multiply_factor = 10 ** decimal_places;

    switch (type) {
    case 'string':
        return String(value);
    case 'number':

        if (is_display) {
            // return as string
            return String(Math.round(value * multiply_factor) / multiply_factor);
        }

        return Math.round(value * multiply_factor) / multiply_factor;
    case 'integer':

        if (is_display) {
            // return as string
            return String(Math.round(value));
        }

        return Math.round(value);
    case 'currency':
        if (is_display) {
            return numberWithCommas(value, decimal_places);
        }

        return Math.round(value * 100) / 100;
    default:
        // default as string
        return String(value);
    }
};

/**
 * Where we want to format an entire struct in the same way
 * @param {struct} skv_items Struct of values passed in to change
 * @param {string} type Data type e.g string, number
 * @param {boolean} is_display to determine whether return a string and will handle decimal
 * from being rounded
 * @param {number} decimal_places decimal places to round to
 * @returns {struct} Struct of values changed
 */
const formatStruct = (
    skv_items,
    type,
    is_display = true,
    decimal_places = 0,
) => {
    const skv_return = {};

    // convert object to key's array
    const keys = Object.keys(skv_items);

    // iterate over object
    keys.forEach((key) => {
        // do a check to handle for nested structs
        if (typeof skv_items[key] === 'object') {
            // recurse
            skv_return[key] = formatStruct(skv_items[key], type, is_display, decimal_places);
        } else {
            skv_return[key] = format(skv_items[key], type, is_display, decimal_places);
        }
    });

    return skv_return;
};

export {
    format,
    numberWithCommas,
    formatStruct,
};