Could I parse to `json/[object] using xlsx-populate - node.js

I want to parse an array of objects into xlsx-populate so it can give me the excel file.
const xlsxPopulate = require('xlsx-populate');
const worksheet = await xlsxPopulate.fromBlankAsync();
const sheet1 = worksheet.sheet('Sheet1');
sheet1.cell('A1').value(newArray);
await worksheet.toFileAsync('./myFileName.xlsx');

It works for Arrays or Arrays([[..][..]]) using range or using single cell as well.
From the doc:
xlsx-populate also supports ranges of cells to allow
parsing/manipulation of multiple cells at once.
const r = workbook.sheet(0).range("A1:C3");
// Set all cell values to the same value:
r.value(5);
// Set the values using a 2D array:
r.value([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]);
// Set the values using a callback function:
r.value((cell, ri, ci, range) => Math.random());
Alternatively, you can set the values in a range with only the
top-left cell in the range:
workbook.sheet(0).cell("A1").value([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]);
So all you need to do is converting objects to CSV maybe for an example JS object:
Modified(only removed the .joins) From this answer:
const json = [
{
h1:1,
h2:2
},
{
h1:3,
h2:4
}
];
var fields = Object.keys(json[0])
var replacer = function(key, value) { return value === null ? '' : value }
var csv = json.map(function(row){
return fields.map(function(fieldName){
return JSON.stringify(row[fieldName], replacer)
})
})
csv.unshift(fields) // add header column
console.log(csv) //[ [ 'h1', 'h2' ], [ '1', '2' ], [ '3', '4' ] ]

Related

Node.js db results to chartist.js reformat

I can hardcode data (labels and series) for a chartist, but need help figuring out how to reformat a db query result.
The app.js contains
const ParmLocation = req.query.ParmLocation
const ParmLine = req.query.ParmLine
console.log("pls2 page requested for " + ParmLocation + " Line " + ParmLine)
// execute a database query
const userToken = db.DBQueryBHBrowser("select PrinterType, count(1) as PCount from printerNames Group by PrinterType");
userToken.then(function(result) {
console.log(JSON.stringify(result.recordset));
res.render('chartpage', {ParmLocation: ParmLocation, ParmLine: ParmLine, S2: result.recordset});
...
The chartpage.js contains below with "data" that works and is in the format needed.
...
var data = {
// A labels array that can contain any sort of values
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
// Our series array that contains series data arrays
series: [[5, 2, 4, 2, 0]]
};
var options = { };
// Create charts with data and options
new Chartist.Line('#TargetRate', data, options);
new Chartist.Line('#SecondShift', {{S2}}, options);
Console log of result.recordset:
[
{ PrinterType: 'Dymo400', PCount: 8 },
{ PrinterType: 'Dymo450', PCount: 30 },
{ PrinterType: 'Dymo4XL', PCount: 13 },
{ PrinterType: 'Laser', PCount: 8 },
{ PrinterType: 'Sato', PCount: 2 }
]
This seemed to work for my purposes
result.recordset.forEach(function(row){
labels.push(Object.values(Object.values(row))[0]);
series.push(Object.values(Object.values(row))[1]);
});
const chartdata = { labels: labels, series: series};

I fetch data from an API in postgress database using pg pool with Nodejs. I get data in 2D array each array is candle information

This is the format of data I receive.
[
[
1627875900,
15874.9,
15876.9,
15834.65,
15847.05,
0
],
[
1627875960,
15847.05,
15853,
15838.7,
15853,
0
],
[
1627876020,
15854.25,
15861.85,
15853.6,
15861.05,
0
],
[
1627876080,
15860.35,
15862.85,
15856,
15859.4,
0
]
]
If I use loop to store it then order changes because of async. Please help me in this direction how to store or store at once with each array element as a record.
here is my snippet.
const newCandle = response.candles.map(async (element) => {
await pool.query(
`INSERT INTO nifty_50 (date, open, high, low, close) VALUES ('${element[0]}', '${element[1]}', '${element[2]}', '${element[3]}', '${element[4]}')`
);
});
You have two options for inserting in database:
Convert record to flatten array and use params
function expand(rowCount, columnCount, startAt=1){
var index = startAt
return Array(rowCount).fill(0).map(v => `(${Array(columnCount).fill(0).map(v => `$${index++}`).join(", ")})`).join(", ")
}
// flatten([[1, 2], [3, 4]]) returns [1, 2, 3, 4]
function flatten(arr){
var newArr = []
arr.forEach(v => v.forEach(p => newArr.push(p)))
return newArr
}
const response = {
candles: [
[
1627875900,
15874.9,
15876.9,
15834.65,
15847.05,
0
],
[
1627875960,
15847.05,
15853,
15838.7,
15853,
0
]
]
};
const candles = response.candles.map((v) => ([v[0], v[1], v[2], v[3], v[4]]));
await pool.query(
`INSERT INTO nifty_50 (date, open, high, low, close) VALUES ${expand(candles.length, 5)}`,
flatten(candles),
);
Use Postgres insert/select query (if all array data has been number format)
await pool.query(
`INSERT INTO nifty_50 (date, open, high, low, close) SELECT t.data[i][1], t.data[i][2], t.data[i][3], t.data[i][4], t.data[i][5] FROM (SELECT $1::NUMERIC[][] AS data) t CROSS JOIN generate_series(1, array_length(t.data, 1)) i`,
[response.candles],
);

How to copy an array of object and change only objects indexes using Ramda?

I am receiving an array like this: Steps: [{ One: 1, Two: 2, }, {One: 3, Two: 4, }]
and I want to copy this array Steps only changing the indexes to lowercase, like one and two, copying the values..
How I can do this using ramda?
This generic mapKeys functions accepts another function to transform the keys (R.toLower in this case). The function converts the object to entries with R.toPairs, evolves the 1st item of each entry (the key) using the supplied function (cb), and then converts the entries back to object using R.fromPairs.
const { pipe, toPairs, map, evolve, fromPairs, toLower } = R
const mapKeys = cb => pipe(
toPairs,
map(evolve([cb])),
fromPairs,
)
const steps = [{ One: 1, Two: 2, }, { One: 3, Two: 4 }]
const result = map(mapKeys(toLower))(steps) // call mapKeys on an array of objects
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

Lodash - Using _.update inside _.forEach

I'm trying to use the _.update method inside of the _.forEach method and I'm not understanding why the newly added property has a value of undefined.
FYI, I have to have the function defined separately and then pass it to the _.update method, I can't write it directly into the _.update method (it must be dynamic).
I've tried structuring this in multiple different ways, but none of them work.
let object = [{ 'a': 1, 'b': 1 }, { 'a':1, 'b': 1 }]
function myFunc (row) { return row.a + row.b }
_.forEach(object, row => _.update(row, 'c', myFunc(row)))
console.log(object)
I expected to get:
[{ 'a': 1, 'b': 1, 'c': 2 }, { 'a':1, 'b': 1, 'c': 2 }]
The _.update() method is used for updating an existing property, and it accepts an updater function, and not a value (like the one generated by myFunc).
In your case you should use _.set(), that accepts a value:
const object = [{ 'a': 1, 'b': 1 }, { 'a':1, 'b': 1 }]
function myFunc(row) {
return row.a + row.b
}
_.forEach(object, row => _.set(row, 'c', myFunc(row)))
console.log(object)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
And if you don't have to use lodash, you can use Array.forEach():
const object = [{ 'a': 1, 'b': 1 }, { 'a':1, 'b': 1 }]
object.forEach(row => row.c = myFunc(row))
function myFunc(row) {
return row.a + row.b
}
console.log(object)

Running reduce function twice on an array ? results in an undefined node js

I am having issues with node js. I am thinking this has to do with how the code runs async.
Is it because that the reduce function is running asynchronously ?
If so what is the idiomatic pattern I must follow inorder to run these function one after another?
I am trying to run reduce operation twice and the second time I am getting an undefined
function hello () {
var values = [
{"a": 1},
{"b": 2},
{"c": 3},
{"d": 4},
{"b": 5},
{"a": 6},
{"a": 7},
{"b": 8},
{"c": 9},
{"d": 10}
];
var kvList = values.reduce(function (result, element) {
var key = Object.keys(element);
var val = element[key];
// if undefined create an array.
result[key] = result[key] || [];
result[key].push(val);
return result;
}, []);
console.log(kvList);
console.log(kvList[0]); // becomes undefined here.
var pairs = kvList.reduce(function (result, element) {
console.log("HELLO");
var key = Object.keys(element)[0];
console.log(element);
var subArray = element[key];
var total = subArray.reduce(function (result, element) {
return result + element;
}, 0);
result[key] = total;
return result;
}, []);
console.log(pairs);
};
hello();
Array.prototype.reduce() does not run asynchronously.
The issue is that .reduce() operates on array elements (sequentially numbered elements that are accessed via a numeric index starting at 0). Your first array has array elements. The result of your first .reduce() however is an array object, but has only properties such as 'a', 'b', 'c' and and no actual array elements. For example, after your first .reduce() operation, kvList.length === 0 so the second .reduce() does not cycle through the elements like you want it to.
The culprit in the first .reduce() loop are these lines of code:
// if undefined create an array.
result[key] = result[key] || [];
result[key].push(val);
This adds a property to result with the property name key. It does not actually add an element to the array so the second .reduce() then has no array elements to operate on.
OK, now that you've shown the desired result, this generates that result:
var values = [
{"a": 1}, {"b": 2}, {"c": 3}, {"d": 4}, {"b": 5},
{"a": 6}, {"a": 7}, {"b": 8}, {"c": 9}, {"d": 10}
];
var dict = {};
values.forEach(function(obj) {
// iterate the properties of each object in the array
for (var prop in obj) {
// if not already in the dict, add an empty array to the dict for this property name
if (!(prop in dict)) {
dict[prop] = [];
}
// add this number to the array for this dict entry
dict[prop].push(obj[prop]);
}
});
// dict is {"a":[1,6,7],"b":[2,5,8],"c":[3,9],"d":[4,10]}
// process back into an array
var result = [];
// iterate each property in the dict
for (var prop in dict) {
// create an object that is of this form {prop: [val1, val2, val3]}
// and put it in the result array
var temp = {};
temp[prop] = dict[prop];
result.push(temp);
}
// result is [{"a":[1,6,7]},{"b":[2,5,8]},{"c":[3,9]},{"d":[4,10]}]
Working demo: http://jsfiddle.net/jfriend00/q8u208y4/
FYI, your data structures of an object with a single key are somewhat weird and hard to work with. I'm wondering why the final result isn't what's in dict which is actually easier to work with in code since you can just iterate the properties directly to get each property and corresponding array.

Resources