Reusable Node Code Modules, Part 12 - Data Transformation and Formatting
Optimizing Data Flow: Building Reusable Data Transformation and Formatting Modules
Data transformation and formatting are crucial for ensuring that data is consistent, clean, and suitable for further processing or presentation. Implementing reusable data transformation and formatting modules ensures consistency and efficiency across projects. This guide covers how to structure reusable data transformation and formatting modules in Node.js using Express, manage data transformation efficiently, and integrate common libraries.
Common Libraries and Tools
1. Lodash
Lodash is a utility library delivering consistency, modularity, and performance
Key Features
Utility Functions: Provides a wide range of utility functions for common programming tasks
Performance: Optimized for performance with low overhead
Modular: Supports individual function imports to reduce bundle size
Consistency: Ensures consistent behavior across different environments
2. Moment.js (and alternatives)
Moment.js is a popular library for parsing, validating, manipulating, and formatting dates. Alternatives include Day.js and date-fns
Key Features
Date Manipulation: Comprehensive date manipulation capabilities
Formatting: Extensive date formatting options
Locales: Supports multiple locales
Plugins: Rich ecosystem of plugins for additional functionality
3. Numeral.js
Numeral.js is a library for formatting and manipulating numbers
Key Features
Number Formatting: Supports various number formats including currency, percentages, and custom formats
Locale Support: Provides localization for number formats
Parsing: Parses numbers from formatted strings
Lightweight: Minimal footprint and easy to use
4. Joi
Joi is a powerful schema description language and data validator for JavaScript objects
Key Features
Validation: Validates JavaScript objects based on schema definitions
Transformation: Supports transformation of data during validation
Custom Rules: Allows creation of custom validation rules
Integration: Easily integrates with Express and other frameworks
Comparison
Lodash: Best for general-purpose utility functions with a focus on performance and modularity.
Moment.js: Ideal for comprehensive date manipulation and formatting, with Day.js and date-fns as lightweight alternatives.
Numeral.js: Suitable for flexible and localized number formatting and manipulation.
Joi: Best for schema-based data validation and transformation with support for custom rules.
Examples and Wrapper Class
Example 1: Lodash
Setup:
$ npm install lodash
Configuration:
import _ from 'lodash';
const transformData = (data) => {
return _.map(data, item => _.pick(item, ['id', 'name', 'value']));
};
export default transformData;
Wrapper Class:
class DataTransformer {
constructor() {
this._ = _;
}
transform(data) {
return this._.map(data, item => this._.pick(item, ['id', 'name', 'value']));
}
}
export default new DataTransformer();
Example 2: Moment.js
Setup:
$ npm install moment
Configuration:
import moment from 'moment';
const formatDate = (date, format) => {
return moment(date).format(format);
};
export default formatDate;
Wrapper Class:
class DateFormatter {
constructor() {
this.moment = moment;
}
format(date, format) {
return this.moment(date).format(format);
}
parse(dateString, format) {
return this.moment(dateString, format).toDate();
}
}
export default new DateFormatter();
Example 3: Numeral.js
Setup:
$ npm install numeral
Configuration:
import numeral from 'numeral';
const formatNumber = (number, format) => {
return numeral(number).format(format);
};
export default formatNumber;
Wrapper Class:
class NumberFormatter {
constructor() {
this.numeral = numeral;
}
format(number, format) {
return this.numeral(number).format(format);
}
parse(numberString) {
return this.numeral(numberString).value();
}
}
export default new NumberFormatter();
Example 4: Joi
Setup:
$ npm install joi
Configuration:
import Joi from 'joi';
const schema = Joi.object({
id: Joi.number().integer().required(),
name: Joi.string().required(),
value: Joi.number().required()
});
const validateData = (data) => {
const { error, value } = schema.validate(data);
if (error) {
throw new Error(`Validation error: ${error.message}`);
}
return value;
};
export default validateData;
Wrapper Class:
class DataValidator {
constructor() {
this.schema = Joi.object({
id: Joi.number().integer().required(),
name: Joi.string().required(),
value: Joi.number().required()
});
}
validate(data) {
const { error, value } = this.schema.validate(data);
if (error) {
throw new Error(`Validation error: ${error.message}`);
}
return value;
}
extend(schemaExtension) {
this.schema = this.schema.keys(schemaExtension);
}
}
export default new DataValidator();