zemirco / json2csv

Convert json to csv with column titles
http://zemirco.github.io/json2csv
MIT License
2.71k stars 364 forks source link

Parsing failing for JsonArray type input #553

Closed kanibs closed 2 years ago

kanibs commented 2 years ago

I am trying to parse a JSON to CSV using json2csv. The JSON I have to parse is

{
    "meta": {
        "request": {
            "page": 1,
            "format": "json",
            "start_date": "2021-11-01",
            "end_date": "2021-11-30",
            "country": "gb"
        },
        "status": "Success",
        "last_updated": "2021-11-30"
    },

    "top_sites": [
        {
            "rank": 1,
            "domain": "song1"
        },
        {
            "rank": 2,
            "domain": "song2"
        }
    ]   

}

What I want is 2 rows of data along with a header. The header should be top_sites.rank and top_sites.domain. Then followed by 2 rows of data for rank 1 and rank 2.

"top_sites.domain" ,  "top_sites.rank"
"song1"        ,                  1
"song2"       ,                   2

I am using json2csv as a module in one of my node scripts. But not able to parse this JSON.

Can someone please help out?

Also, when I try parsing this on the command line using the command json2csv -i test_file.json --unwind top_sites -f 'top_sites.domain,top_sites.rank' then it parses the data well but does not work as such in programmatic access.

The code for programmatic access that I am using is:

const { Parser, transforms: { unwind } } = require('json2csv');
    const nfields = ['top_sites.rank', 'top_sites.domain'];
    const transforms = [unwind({ paths: ['top_sites'] })];
    const json2csvParser = new Parser({ nfields, transforms });
    const csv = json2csvParser.parse(json);

I am using json2csv version 5.0.6 Node version: v12.9.0

juanjoDiaz commented 2 years ago

You only mistake is to use nfields instead of fields.

const { Parser, transforms: { unwind } } = require('json2csv');

const data = {
    "meta": {
        "request": {
            "page": 1,
            "format": "json",
            "start_date": "2021-11-01",
            "end_date": "2021-11-30",
            "country": "gb"
        },
        "status": "Success",
        "last_updated": "2021-11-30"
    },

    "top_sites": [
        {
            "rank": 1,
            "domain": "song1"
        },
        {
            "rank": 2,
            "domain": "song2"
        }
    ]   

};

const fields = ['top_sites.rank', 'top_sites.domain'];
const transforms = [unwind({ paths: ['top_sites'] })];
const json2csvParser = new Parser({ fields, transforms });
const csv = json2csvParser.parse(data);

console.log(csv);

works and outputs

"top_sites.rank","top_sites.domain"
1,"song1"
2,"song2"

Using the CLI you should be able to do the same.

kanibs commented 2 years ago

Thanks, @juanjoDiaz for the reply and help. I am not very versed with JS, so as per your comment, it means we need to have the variable name as fields only and not, say, myFields, or fields_to_scrape?

juanjoDiaz commented 2 years ago

You can name the variable as you want if you use full syntax:

const myRandomVariableContainingTheFields = ['top_sites.rank', 'top_sites.domain'];
const transforms = [unwind({ paths: ['top_sites'] })];
const json2csvParser = new Parser({ fields: myRandomVariableContainingTheFields, transforms });

but using shorthand syntax:

const json2csvParser = new Parser({ myRandomVariableContainingTheFields, transforms });

is equivalent to:

const json2csvParser = new Parser({ myRandomVariableContainingTheFields: myRandomVariableContainingTheFields, transforms: transforms });

The the name of the config options are wrong.

kanibs commented 2 years ago

:) Aah, I realize my fault now. A pretty dumb question that was.

JS Fundamental that was.

Thanks for the Explanation.