property-set
Intelligently set properties on an object using a string with dot-notation.
Installation
npm i -S prop-set
Simple Example
This module was specifically written for mapping data from one source onto an object so that you can easily maintain a mapping file. However, let's take a single, simple example first.
To be clear, this is an example and doesn't represent the most efficient way to set a propery's value. I wouldn't use this module for that.
Let's take the case where you want to set a value in the userAccount
object. We want to map the profile.contactInfo.phoneNumber
property, we want to set it to (555) 867-5209
.
const propSet = require('prop-set')
let userAccount = {}
propSet(userAccount, 'profile.contactInfo.phoneNumber', '(555) 867-5209')
We passed in a blank object so the output is:
{
"profile": {
"contactInfo": {
"phoneNumber": "(555) 867-5209"
}
}
}
Usage
Let's take the case where you have a CSV file who's columns you need to map into an object. You can either manually map these and edit your code every time, or create a config file.
csv-config-file.json
[
{ "from": "#rack", "to": "rack" },
{ "from": "rack_position_bottom", "to": "location.rackUnit" },
{ "from": "equipment", "to": "device.equipmentType" },
{ "from": "service_tag", "to": "serialNumber" },
{ "from": "service_tag", "to": "device.serialNumber" },
{ "from": "node_name", "to": "device.hostName" },
{ "from": "mac_address", "to": "device.primaryMac" },
{ "from": "instance_type", "to": "device.node" }
]
You can now import this file and iterate through the mappings, including mapping the same property to two places if necessary.
index.js
const propSet = require('prop-set'),
csvConfig = require('./csv-config-file')
// Splits by comma, then returns the name and index for later mapping.
const mapHeader = lineOne => lineOne.split(',').map((columnName, index) => ({ name: columnName, column: index }))
const rows = [{...}, {...}, {...}], // This represents a CSV file split by new lines
columns = mapHeader(rows[0]), // This assumes the first row is a header
maxRows = rows.length // Set the upper bounds so it doesn't need to calculate every loop.
for (let i = 1; i < maxRows; i++) {
const columns = rows[i].split(',')
let newRecord = {}
csvConfig.forEach(configMap => {
// Idenitfy which column index the data should come from.
const thisColumnInt = csvColumns.find(i => i.name === configMap.from).column
stringPathSet(newRecord, configMap.to, columns[thisColumnInt])
})
// Output the newly generated and mapped object
console.info(newRecord)
}