json-2-csv
json-2-csv copied to clipboard
Empty Array Being Returned as Header causing JSON to be Outputted in CSV
Background Information
- Module Version:
3.7.8
- Node/Browser Version:
86.0.4240.80
The issue I'm reporting is with:
- [x] json2csv
- [ ] csv2json
I have...
- [x] searched to see if an issue has already been reported.
- [x] verified that my JSON/CSV data is valid (using something like http://jsonlint.com or https://csvlint.io/).
- [x] tried upgrading to the latest version of json-2-csv (since the issue may already be fixed).
Expected Behavior
entities.id,entities.name,entities.siblings.entity.name,entities.siblings.relationship_set.relationships.relationship.name
4,Zeus,Exo,Senior
4,Zeus,Chrono,null
Actual Behavior
entities.id,entities.name,entities.siblings.entity.name,entities.siblings.relationship_set.relationships.relationship.name,entities.siblings.relationship_set.relationships
4,Zeus,Exo,Senior,"{""relationship"":{""name"":""Senior""}}"
4,Zeus,Chrono,null,
Data Sample
JSON:
{
"entities":
{
"id": 4,
"name": "Zeus",
"siblings": [
{
"entity": {
"name": "Exo",
},
"relationship_set": {
"relationships": [
{
"relationship": {
"name": "Senior"
},
},
]
}
},
{
"entity": {
"name": "Chrono"
},
"relationship_set": {
"relationships": []
}
}
]
}
}
Code Example
// Please include a simple example to replicate the issue
let converter = require('json-2-csv');
const obj1 = {
"entities":
{
"id": 4,
"name": "Zeus",
"siblings": [
{
"entity": {
"name": "Exo",
},
"relationship_set": {
"relationships": [
{
"relationship": {
"name": "Senior"
},
},
]
}
},
{
"entity": {
"name": "Chrono"
},
"relationship_set": {
"relationships": []
}
}
]
}
}
converter.json2csv(obj1, (err, csv) => {
console.log(csv)
}, { unwindArrays: true, expandArrayObjects: true })
To note, while messing around I found a way to get the expected output, but do not think it is the correct solution as it causes a test to fail. I solved it by updating deeks.generateDeepKeysList
to return no key if there is an array to recur on but it is empty:
} else if (isArrayToRecurOn(data[currentKey]) && !data[currentKey].length) {
return []
}
and then changing json-2-csv.utils
, where we "push an empty string so the value is empty since there are no values" to instead push an empty array instead of an empty string:
path.setPath(cloned, fieldPath, []);
This is obviously not the right solution, however it brings about the expected output and may help you find the correct solution.
I'm having a similar issue, but with Objects. E.g.:
const test_json = [
{
a: 1,
b: 2,
c: {
ca: 1,
cb: 2,
},
},
{
a: 3,
b: 4,
c: {},
},
]
json2csvAsync(test_json).then(console.log) //?
result:
a,b,c.ca,c.cb,c
1,2,1,2,"{""ca"":1,""cb"":2}"
3,4,undefined,undefined,{}
I've looked through the docs to see how I might address this, but I've come up with nothing... Any tips?
🙏
@loganpowell I switched to https://github.com/kaue/jsonexport but I recommend using my fork from this PR: https://github.com/kaue/jsonexport/pull/90
@hdwatts I tried that, but that leaves something to be desired as well. I'll follow up on that PR. with more info
I've used a work around to make sure a null set is present to keep the object structures similar and that is working for me atm... e.g.:
const test_json = [
{
a: 1,
b: 2,
c: {
ca: 1,
cb: 2,
},
},
{
a: 3,
b: 4,
c: {},
},
]
const xfd = test_json.reduce((acc, cur) => {
const null_set = { ca: null, cb: null }
const { c, ...rest } = cur
return acc.push({ ...((c.ca && { c }) || { c: null_set }), ...rest }), acc
}, [])
json2csvAsync(xfd).then(console.log) //?
result:
c.ca,c.cb,a,b
1,2,1,2
null,null,3,4
Hit the same issue as @loganpowell with an empty object yielding an unwanted JSON-filled column. Used a similar workaround.
Thanks for bringing this up again. I'm trying to make some progress on these issues and will take another look to see if I can find a solution to resolve this since I agree that the behavior of printing a JSON object's representation isn't ideal.
It happens the same to me