mrodrig / json-2-csv

Convert JSON to CSV *or* CSV to JSON!
https://mrodrig.github.io/json-2-csv
MIT License
420 stars 58 forks source link

"expandArrayObjects" option not behaving as expected #235

Closed himan085 closed 1 year ago

himan085 commented 1 year ago

Background Information

The issue I'm reporting is with:

I have...

Expected Behavior

When using the json2csv() API and not passing any props the default behaviour in the README is mentioned for expandArrayObjects to be treated as false. Hence the objects in array values should NOT be deep-converted to CSV. But it is in fact the array objects are getting deep-converted to CSV. I explicitly tried setting {expandArrayObjects: false} as the options but the issue is still present.

Actual Behavior

Ideally the objects in array values should NOT be deep-converted to CSV if there is no options defined or if the {expandArrayObjects: false} options is used.

Data Sample

CSV:

Make,Model,Year,Specifications.Mileage,Specifications.Trim
Nissan,Murano,2013,7106,S AWD
BMW,X5,2014,3287,M

(or)

JSON:

let documents = [
    {
        Make: 'Nissan',
        Model: 'Murano',
        Year: '2013',
        Specifications: {
            Mileage: '7106',
            Trim: 'S AWD'
        }
    },
    {
        Make: 'BMW',
        Model: 'X5',
        Year: '2014',
        Specifications: {
            Mileage: '3287',
            Trim: 'M'
        }
    }
];

Code Example

const csvString = await json2csv(documents);

OR ---

const csvString = await json2csv(documents, { expandArrayObjects: false });

I'm using the below code to unblock myself:

const csvString = await json2csv(documents, { keys: Object.keys(documents[0]) });
mrodrig commented 1 year ago

Hi @himan085, thanks for reporting this. From what I'm understanding, I believe the behavior you're seeing for the expandArrayObjects option is correct in this case since it's currently targeted to just expanding objects appearing inside an array within the top-level object that is being converted. For example, the specifications field here contains an array, so setting the option to true will result in specifications.features and specifications.mileage being used as keys, and setting the option to false will result in just specifications being used:

[
    { 
        "specifications": [
            { "features": [...] },
            { "mileage": "5000" }
        ]
    }
]

Unfortunately, I don't think there's currently an option that handles whether nested objects, like in the example you included, should be expanded or not. I can see that it's useful to have such an option in certain cases though.

I'll take a look at how it could be implemented, but I'm also open to a merge request if you or someone else beats me to implementing this. 🙂

mrodrig commented 1 year ago

This ended up being a simple addition, so there's now an expandNestedObjects option in release version 4.1.0 that you can use for this use case:

let documents = [
    {
        Make: 'Nissan',
        Model: 'Murano',
        Year: '2013',
        Specifications: {
            Mileage: '7106',
            Trim: 'S AWD'
        }
    },
    {
        Make: 'BMW',
        Model: 'X5',
        Year: '2014',
        Specifications: {
            Mileage: '3287',
            Trim: 'M'
        }
    }
];

const csvString = await json2csv(documents, { expandNestedObjects: false });

Hope this helps!

himan085 commented 1 year ago

Thanks for your prompt help @mrodrig ! Really appreciate.