Search code examples
javascriptjsonlodashstringify

How to add [] opening and closing square brackets around a JSON in Javascript?


1. I am building a JSON file

    const _ = require('lodash');

    let dataGroupedByMndtId = _.groupBy(
        _.orderBy(data.Entries, 'mndtId'), 'mndtId'
    );

    let transactionsPerEntry = [];
    _
        .map(dataGroupedByMndtId, (transactions, index) => {
            // verticalBarChartData.push(`{ "name": "${index}"}`);

            _.map(
                transactions, (transaction, index) => {

                    transactionsPerEntry.push(`{ "name": "${transaction.date}", "value": "${transaction.amount}"}`);
                }
            );
            verticalBarChartData.push(`{ "name": "${index}", "series": [${transactionsPerEntry}]}`);
            transactionsPerEntry = [];

        });

    outputJsonFile = 'generated.json';
    outputJsonPath = path.join(__dirname, 'data', outputJsonFile);

    try {
        fs.writeFileSync(outputJsonPath, verticalBarChartData, { mode: 0o755 });
    } catch (err) {
        // An error occurred
        console.error(err);
    }

2. The generated JSON misses enclosing square brackets

    {
        "name": "1/0003/1",
        "series": [{
            "name": "2019-04-05T00:00:00Z",
            "value": 20.87
        }, {
            "name": "2019-03-03T00:00:00Z",
            "value": 5.74
        }]
    }, {
        "name": "1/0004/1",
        "series": [{
            "name": "2019-04-03T00:00:00Z",
            "value": 15.7
        }, {
            "name": "2019-03-26T00:00:00Z",
            "value": 0.13
        }]
    }

QUESTION

How could I add enclosing square brackets?

I tried several ways :

  1. adding enclosing brackets (stringify) and parsing the string (JSON.parse) but the square brackets disappear

  2. add [] around the verticalBarChart variable

  3. push an empty item

thank you for your help


Solution

  • I would strongly recommend not handcrafting JSON. Instead, build the structure and then let JSON.stringify do the work.

    You're also misusing _.map. If you aren't returning a value from its callback and you're not using _.map's return value, _.map is the wrong tool. You'd use _.each instead. (Or use ES5's forEach.) Or of course, return something from the callback and use the returned result, since you do seem to be doing a mapping operation.

    Here's what I think you're trying to do:

    const _ = require('lodash');
    
    let dataGroupedByMndtId = _.groupBy(
        _.orderBy(data.Entries, 'mndtId'), 'mndtId'
    );
    
    let verticalBarChartData = _.map(dataGroupedByMndtId, (transactions, index) => ({
        name: String(index), // You seem to want it to be a string, not a number
        series: _.map(transactions, (transaction, index) => ({
            name: transaction.date,     // May need String() around that
            value: transaction.amount   // And may need String() here too, if you really want a string
        }))
    }));
    
    outputJsonFile = 'generated.json';
    outputJsonPath = path.join(__dirname, 'data', outputJsonFile);
    
    try {
        fs.writeFileSync(outputJsonPath, JSON.stringify(verticalBarChartData), { mode: 0o755 });
    } catch (err) {
        // An error occurred
        console.error(err);
    }
    

    I've used _.map there because you were, but you could just as easily use ES5's Array.prototype.map.