Skip to content

Commit

Permalink
Add unwindIgnoreEmptyArrays option.
Browse files Browse the repository at this point in the history
In order to convert the generated CSV back to the most accurate JSON
possible, the module must still insert `[]` for unwound empty array
values. However, there are some legitimate cases where users want to be
able to have the module ignore these values so that the generated CSV is
a bit more user-friendly, depending on the data being converted. This
new option allows users the ability to achieve this without impacting
existing use cases, as the user has opted to specify an option which may
impact the ability to convert the CSV back to JSON later on.

Fixes #168
  • Loading branch information
mrodrig authored Jun 1, 2021
1 parent bf4dd22 commit 0def033
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 11 deletions.
1 change: 1 addition & 0 deletions lib/constants.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"checkSchemaDifferences": false,
"expandArrayObjects": false,
"unwindArrays": false,
"unwindIgnoreEmptyArrays": false,
"useDateIso8601Format": false,
"useLocaleFormat": false,
"parseValue": null,
Expand Down
5 changes: 3 additions & 2 deletions lib/json2csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ const Json2Csv = function(options) {
deeksOptions = {
expandArrayObjects: expandingWithoutUnwinding,
ignoreEmptyArraysWhenExpanding: expandingWithoutUnwinding,
escapeNestedDots: true
escapeNestedDots: true,
ignoreEmptyArrays: options.unwindIgnoreEmptyArrays
};

/** HEADER FIELD FUNCTIONS **/
Expand Down Expand Up @@ -201,7 +202,7 @@ const Json2Csv = function(options) {

// Unwind each of the documents at the given headerField
params.headerFields.forEach((headerField) => {
params.records = utils.unwind(params.records, headerField);
params.records = utils.unwind(params.records, headerField, options);
});

return retrieveHeaderFields(params.records)
Expand Down
8 changes: 4 additions & 4 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ function getNCharacters(str, start, n) {
* @param item {any}
* @param fieldPath {String}
*/
function unwindItem(accumulator, item, fieldPath) {
function unwindItem(accumulator, item, fieldPath, options) {
const valueToUnwind = path.evaluatePath(item, fieldPath);
let cloned = deepCopy(item);

Expand All @@ -227,7 +227,7 @@ function unwindItem(accumulator, item, fieldPath) {
});
} else if (Array.isArray(valueToUnwind) && valueToUnwind.length === 0) {
// Push an empty string so the value is empty since there are no values
path.setPath(cloned, fieldPath, '');
path.setPath(cloned, fieldPath, options.unwindIgnoreEmptyArrays ? [] : '');
accumulator.push(cloned);
} else {
accumulator.push(cloned);
Expand All @@ -240,10 +240,10 @@ function unwindItem(accumulator, item, fieldPath) {
* @param field {String}
* @returns {Array<any>}
*/
function unwind(array, field) {
function unwind(array, field, options) {
const result = [];
array.forEach((item) => {
unwindItem(result, item, field);
unwindItem(result, item, field, options);
});
return result;
}
Expand Down
1 change: 1 addition & 0 deletions test/config/testCsvFilesList.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const fs = require('fs'),
{key: 'csvEmptyLastValue', file: '../data/csv/csvEmptyLastValue.csv'},
{key: 'unwind', file: '../data/csv/unwind.csv'},
{key: 'unwindEmptyArray', file: '../data/csv/unwindEmptyArray.csv'},
{key: 'unwindIgnoreEmptyArrays', file: '../data/csv/unwindIgnoreEmptyArrays.csv'},
{key: 'unwindWithSpecifiedKeys', file: '../data/csv/unwindWithSpecifiedKeys.csv'},
{key: 'withSpecifiedKeys', file: '../data/csv/withSpecifiedKeys.csv'},
{key: 'localeFormat', file: '../data/csv/localeFormat.csv'},
Expand Down
1 change: 1 addition & 0 deletions test/config/testJsonFilesList.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = {
csvEmptyLastValue: require('../data/json/csvEmptyLastValue'),
unwind: require('../data/json/unwind'),
unwindEmptyArray: require('../data/json/unwindEmptyArray'),
unwindIgnoreEmptyArrays: require('../data/json/unwindIgnoreEmptyArrays'),
localeFormat: require('../data/json/localeFormat'),
invalidParsedValues: require('../data/json/invalidParsedValues'),
firstColumnWrapCRLF: require('../data/json/firstColumnWrapCRLF.json'),
Expand Down
3 changes: 3 additions & 0 deletions test/data/csv/unwindIgnoreEmptyArrays.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
entities.id,entities.name,entities.siblings.entity.name,entities.siblings.relationship_set.relationships.relationship.name
4,Zeus,Exo,Senior
4,Zeus,Chrono,
33 changes: 33 additions & 0 deletions test/data/json/unwindIgnoreEmptyArrays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[
{
"entities":
{
"id": 4,
"name": "Zeus",
"siblings": [
{
"entity": {
"name": "Exo"
},
"relationship_set": {
"relationships": [
{
"relationship": {
"name": "Senior"
}
}
]
}
},
{
"entity": {
"name": "Chrono"
},
"relationship_set": {
"relationships": []
}
}
]
}
}
]
19 changes: 14 additions & 5 deletions test/json2csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -656,15 +656,24 @@ function runTests(jsonTestData, csvTestData) {
});
});

// Test case for #168
it('should ignore empty arrays when specified when unwinding arrays', (done) => {
converter.json2csv(jsonTestData.unwindIgnoreEmptyArrays, (err, csv) => {
if (err) done(err);
csv.should.equal(csvTestData.unwindIgnoreEmptyArrays);
done();
}, {
expandArrayObjects: true,
unwindArrays: true,
unwindIgnoreEmptyArrays: true
});
});

// Test case for #184
it('should handle keys with nested dots when expanding and unwinding arrays', (done) => {
converter.json2csv(jsonTestData.nestedDotKeysWithArrayExpandedUnwound, (err, csv) => {
if (err) done(err);

// Replace raw boolean values with quoted versions
let expectedCsv = csvTestData.nestedDotKeysWithArrayExpandedUnwound;

csv.should.equal(expectedCsv);
csv.should.equal(csvTestData.nestedDotKeysWithArrayExpandedUnwound);
done();
}, {
expandArrayObjects: true,
Expand Down

0 comments on commit 0def033

Please sign in to comment.