Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/complex json array unexpected behavior #81

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Change log
----------------------
- v3.2.0 - fix value 0 from being omitted
- v3.0.1 - fix column values with zero (0) are being replaced with "" (sregger)
- v3.0.0 - Promise API & fillTopRow
- v2.5.2 - fix stream memory limit (issue #64)
Expand Down
121 changes: 121 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,127 @@ speed.min,5
size,10;20
```

### Complex JSON Array

#### Code (fillGaps, fillTopRow = true)

```javascript
const jsonexport = require('jsonexport');

const stats = [{
manufacturer: 'BMW',
country: 'USA',
inventory: {
profile: ['public'],
cars: [
{
model: '3-series',
price: '34850'
},
{
model: '5-series',
price: '55000'
},
{
model: '7-series',
price: '72000'
}
]
},
category: [
{
sedan: [
{
seats: 4,
doors: 4,
sunroof: true
}
]
}
],
location: {
address: [
{
city: 'Raleigh',
state: 'NC',
dealer: 'Raleigh Motors'
},
{
city: 'Durham',
state: 'NC',
dealer: 'Durham BMW'
}
]
}
},
{
manufacturer: 'Audi',
country: 'USA',
inventory: {
profile: ['public'],
cars: [
{
model: 'Q3',
price: '36700'
},
{
model: 'Q5',
price: '48900'
},
{
model: 'Q7',
price: '91350'
}
]
},
category: [
{
sedan: [
{
seats: 7,
doors: 4,
sunroof: true,
heatedSeats: 'front'
}
]
}
],
location: {
address: [
{
city: 'Greensboro',
state: 'NC',
dealer: 'Audi Greensboro'
},
{
city: 'Asheville',
state: 'NC',
dealer: 'Asheville Audi Motors'
}
]
}
}
];

jsonexport(stats, {fillGaps: true, fillTopRow: true},
function(err, csv){
if(err) return console.error(err);
console.log(csv);
});
```

#### Result

```
manufacturer,country,inventory.profile,inventory.cars.model,inventory.cars.price,category.sedan.seats,category.sedan.doors,category.sedan.sunroof,location.address.city,location.address.state,location.address.dealer,category.sedan.heatedSeats
BMW,USA,public,3-series,34850,4,4,true,Raleigh,NC,Raleigh Motors
BMW,USA,public,5-series,55000,4,4,true,Durham,NC,Durham BMW
BMW,USA,public,7-series,72000,4,4,true,Durham,NC,Durham BMW
Audi,USA,public,Q3,36700,7,4,true,Greensboro,NC,Audi Greensboro,front
Audi,USA,public,Q5,48900,7,4,true,Asheville,NC,Asheville Audi Motors,front
Audi,USA,public,Q7,91350,7,4,true,Asheville,NC,Asheville Audi Motors,front
```

## Options

In order to get the most of out of this module, you can customize many parameters and functions.
Expand Down
8 changes: 8 additions & 0 deletions dist/parser/csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,18 @@ var Parser = function () {
emptyRowIndexByHeader[elementHeaderIndex] = emptyRowIndexByHeader[elementHeaderIndex] || 0;
// make sure there isnt a empty row for this header
if (self._options.fillTopRow && emptyRowIndexByHeader[elementHeaderIndex] < rows.length) {
// Fill gap between row's current length and elementHeaderIndex with ""
var rowGap = elementHeaderIndex - rows[emptyRowIndexByHeader[elementHeaderIndex]].length;
if (rowGap > 0) {
rows[emptyRowIndexByHeader[elementHeaderIndex]] = rows[emptyRowIndexByHeader[elementHeaderIndex]].concat(Array(rowGap).fill(""));
}
rows[emptyRowIndexByHeader[elementHeaderIndex]][elementHeaderIndex] = self._escape(element.value);
emptyRowIndexByHeader[elementHeaderIndex] += 1;
continue;
}
if (currentRow.length < elementHeaderIndex) {
currentRow = currentRow.concat(Array(elementHeaderIndex - currentRow.length).fill(""));
}
currentRow[elementHeaderIndex] = self._escape(element.value);
emptyRowIndexByHeader[elementHeaderIndex] += 1;
}
Expand Down
12 changes: 11 additions & 1 deletion lib/parser/csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class Parser {

if (this._options.rename && this._options.rename.length > 0)
headers = headers.map((header) => this._options.rename[this._options.headers.indexOf(header)] || header);

if (this._options.forceTextDelimiter) {
headers = headers.map((header) => {
return `${this._options.textDelimiter}${header}${this._options.textDelimiter}`;
Expand Down Expand Up @@ -100,10 +100,20 @@ class Parser {
emptyRowIndexByHeader[elementHeaderIndex] = emptyRowIndexByHeader[elementHeaderIndex] || 0;
// make sure there isnt a empty row for this header
if (self._options.fillTopRow && emptyRowIndexByHeader[elementHeaderIndex] < rows.length) {
// Fill gap between row's current length and elementHeaderIndex with ""
let rowGap = elementHeaderIndex - rows[emptyRowIndexByHeader[elementHeaderIndex]].length;
if (rowGap > 0) {
rows[emptyRowIndexByHeader[elementHeaderIndex]] = rows[emptyRowIndexByHeader[elementHeaderIndex]].concat(
Array(rowGap).fill(""));
}
rows[emptyRowIndexByHeader[elementHeaderIndex]][elementHeaderIndex] = self._escape(element.value);
emptyRowIndexByHeader[elementHeaderIndex] += 1;
continue;
}
if (currentRow.length < elementHeaderIndex) {
currentRow = currentRow.concat(
Array(elementHeaderIndex - currentRow.length).fill(""));
}
currentRow[elementHeaderIndex] = self._escape(element.value);
emptyRowIndexByHeader[elementHeaderIndex] += 1;
}
Expand Down
8 changes: 3 additions & 5 deletions tests/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ var {assert, expect} = require('chai');
var jsonexport = require('../lib/index');
var os = require('os');


const isRemoteTest = process.env.APPVEYOR || process.env.TRAVIS;
if( isRemoteTest ){
console.log('\x1b[34mRemote testing server detected on '+os.type()+' '+os.platform()+' '+os.release()+'\x1b[0m');
Expand Down Expand Up @@ -100,7 +99,7 @@ describe('Object', () => {
if(parent===contacts){
return 'parentless-'+index;
}

return value.toString();
}
}
Expand All @@ -121,9 +120,8 @@ describe('Object', () => {
}
], {})

assert.equal(csv, `a,b,c,d,e\n0,,,1,this`)
assert.equal(csv, `a,b,c,d,e`+ os.EOL +`0,,,1,this`)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, no real changes related to this pull request. Looking for supporting unit tests and none found

});

it('Date', async () => {
const csv = await jsonexport([
{
Expand Down Expand Up @@ -175,4 +173,4 @@ describe('Object', () => {

assert.equal(csv, `a,b,c,d,e,f\n0,,,1,this,replaced-date`)
});
});
});