Closed isaac-martin closed 6 years ago
Can you elaborate a bit more? I'm not sure of what are you trying to achieve :)
Sorry! I am getting data into a legacy manufacturing system and need to follow a very particular set of rules. TSV saved as .txt so all achievable with json2csv Let's use the below code as an example - mine will be more complex but for the sake of simplicity we can use this.
const Json2csvParser = require('json2csv').Parser;
const fields = ['car', 'price', 'color'];
const myCars = [
{
"car": "Audi",
"price": 40000,
"color": "blue",
"location_city" : "New York",
"location_state" : "New York",
"location_country" : "United States",
}, {
"car": "BMW",
"price": 50000,
"color": "red",
"location_city" : "Raleigh",
"location_state" : "North Carolina",
"location_country" : "United States",
},
];
const json2csvParser = new Json2csvParser({ fields , header: false});
const csv = json2csvParser.parse(myCars);
console.log(csv);
Would output the following to console
"Audi", 40000, "blue", "New York", "New York", "United States"
"BMW", 50000, "red", "Raleigh", "North Carolina", "United States"
What I would want to achieve would be something like the below.
"Audi", 40000, "blue",
"New York", "New York", "United States"
"BMW", 50000, "red",
"Raleigh", "North Carolina", "United States"
I see. Thanks for the code example. I assume that you are actually not using the fields
field so ti matches your expected output.
I think that's very specific requirement (and a bit odd one if you allow me).
I don't think that is something that should be inside json2csv since it's not generic enough. But I think that's something that you can easily achieve in your code with some data preprocessing.
const Json2csvParser = require('json2csv').Parser;
const row1fields = ['car', 'price', 'color'];
const row2fields = ['location_city', 'location_state', 'location_country'];
const myCars = [
{
"car": "Audi",
"price": 40000,
"color": "blue",
"location_city" : "New York",
"location_state" : "New York",
"location_country" : "United States",
}, {
"car": "BMW",
"price": 50000,
"color": "red",
"location_city" : "Raleigh",
"location_state" : "North Carolina",
"location_country" : "United States",
},
];
const getObjectProps = (obj, props) => props.reduce((acc, prop, i) => {
acc[i] = obj[prop]; // Use just the index so json2csv treats them as the same colum
return acc;
}, {});
// If you use ES7
// const getObjectProps = (obj, props) => props.reduce((acc, prop, i) => { ...acc, i: obj[prop] });
const processedData = myCars.reduce((acc, row) => {
acc.push(getObjectProps(row, row1fields));
acc.push(getObjectProps(row, row2fields));
}, []);
const json2csvParser = new Json2csvParser({ header: false});
const csv = json2csvParser.parse(processedData);
console.log(csv);
That's just an example I wrote in 2 seconds, there might be mistakes since I didn't run it. And you should adapt it to your coding style.
Does that help?
Perfect, Thanks that will at least steer me in the right direction. Have a nice weekend!
You too!
I'll close this. Feel free to re-open or just ask if you have any more questions :)
Still couldn't figure it out @juanjoDiaz - returns a ReferenceError that acc is not defined inside the getObjectProps function. Understand if you're too busy to help out, this is a little out of my skill level and as you said quite an unusual requirement.
My bad. I told you it wasn't tested. :p
The right function is:
const processedData = myCars.reduce((acc, row) => {
acc.push(getObjectProps(row, row1fields));
acc.push(getObjectProps(row, row2fields));
return acc;
}, []);
Just tested the whole thing and it works :)
Just let me know if you have any other problem :)
So I thought I had this all working until i realized the JSON we are getting can sometimes have nested content inside.
Data would look like this as an example
const myCars = [
{
"car": "Audi",
"price": 40000,
"color": "blue",
"location_city" : "New York",
"location_state" : "New York",
"location_country" : "United States",
"lineitems": [
{
"prod_qty": 1,
"prod_sku": "colorfulpants",
"prod_price": "140.00"
},
{
"prod_qty": 1,
"prod_sku": "blackdress",
"prod_price": "0.00"
}
],
}, {
"car": "BMW",
"price": 50000,
"color": "red",
"location_city" : "Raleigh",
"location_state" : "North Carolina",
"location_country" : "United States",
"lineitems": [
{
"prod_qty": 2,
"prod_sku": "party",
"prod_price": "100.00"
},
{
"prod_qty": 1,
"prod_sku": "sweater",
"prod_price": "0.00"
}
],
},
];
Ideally I need an output like the below - where we are making a new row for each item inside lineitems
"Audi", 40000, "blue",
"New York", "New York", "United States"
"1","colorfulpants","140.00"
"1","blackdress","0.00"
"BMW", 50000, "red",
"Raleigh", "North Carolina", "United States"
"2","party","100.00"
"1","sweater","0"
I've been playing around for a few days but I am not sure this is even going to be possible?
const Json2csvParser = require('json2csv').Parser;
const row1fields = ['car', 'price', 'color'];
const row2fields = ['location_city', 'location_state', 'location_country'];
const rowNestedField = 'lineitems';
const nestedObjectsFields = ['prod_qty', 'prod_sku', 'prod_price'];
const myCars = [
{
"car": "Audi",
"price": 40000,
"color": "blue",
"location_city" : "New York",
"location_state" : "New York",
"location_country" : "United States",
"lineitems": [
{
"prod_qty": 1,
"prod_sku": "colorfulpants",
"prod_price": "140.00"
},
{
"prod_qty": 1,
"prod_sku": "blackdress",
"prod_price": "0.00"
}
],
}, {
"car": "BMW",
"price": 50000,
"color": "red",
"location_city" : "Raleigh",
"location_state" : "North Carolina",
"location_country" : "United States",
"lineitems": [
{
"prod_qty": 2,
"prod_sku": "party",
"prod_price": "100.00"
},
{
"prod_qty": 1,
"prod_sku": "sweater",
"prod_price": "0.00"
}
],
},
];
const getObjectProps = (obj, props) => props.reduce((acc, prop, i) => {
acc[i] = obj[prop]; // Use just the index so json2csv treats them as the same colum
return acc;
}, {});
const getNestedContent = (row, prop, nestedProps) => row[prop]
.map(obj => getObjectProps(obj, nestedProps));
const processedData = myCars.reduce((acc, row) => {
acc.push(getObjectProps(row, row1fields));
acc.push(getObjectProps(row, row2fields));
acc = acc.concat(getNestedContent(row, rowNestedField, nestedObjectsFields))
return acc;
}, []);
const json2csvParser = new Json2csvParser({ header: false});
const csv = json2csvParser.parse(processedData);
console.log(csv);
I expect 10% of your paycheck at the end of the month :p
JK, hope that helps! The "prod_qty" property is not quoted in the result because it's a number and not a string. You can change it also with a bit of preprocessing.
Is it possible to force new rows? Have a format I need to match that has each object over three rows.
Everything I have tried is being stripped out when parsed.