Home > database >  Merge/Update JSON file with an Array
Merge/Update JSON file with an Array

Time:04-19

I have a source.json file, and then another file of changes which I parse, and need to write out the array back to the source file. Here is the source.json structure:

{
    "users" : [
      {
        "id" : "1",
        "name" : "Albin Jaye"
      }
    ],
    "playlists" : [
      {
        "id" : "1",
        "owner_id" : "2",
        "song_ids" : [
          "8",
          "32"
        ]
      }
    ],
    "songs": [
      {
        "id" : "1",
        "artist": "Camila Cabello",
        "title": "Never Be the Same"
      }
    ]
  }

Here is the changes.json structure. I have a CRUD like "add" directive and the "payload" which is the entry to be added to the source file:

{
    "users": [{
        "action": "add",
        "payload": [{
                "id": "1",
                "name": "Albin Jaye"
            },
            {
                "id": "2",
                "name": "Dave Mustaine"
            }
        ]
    }],
    "playlist": [{
        "action": "add",
        "payload": [{
            "id": "1",
            "owner_id": "2",
            "song_ids": [
                "8",
                "32"
            ]
        }]
    }],
    "songs": [{
        "action": "add",
        "payload": [{
            "id": "1",
            "artist": "Camila Cabello",
            "title": "Never Be the Same"
        }]
    }]
}

I have written this code in Node to read in the source file and parse and then read in the changes file. Once the changes file is read, I iterate over and see what "CRUD" directive is there. When I find "add", I then push the payload to an array. After I get finished, when I console log out I get this:

[
  [ 'users', '[object Object],[object Object]' ],
  [ 'playlists', '[object Object]' ],
  [ 'songs', '[object Object]' ]
]

This is swell. BUT, I need now to take this result and Stringify it I think and place it back into the source JSON file in the appropriate place. I think it will be some type of ```fs.appendFile()`` function, but not sure. Here is my code so far:

// Stream in source file
    fs.readFile('./'   inputFile, (err, data) => {
    if (err) throw err;
    let input = JSON.parse(data);
        //console.log(input);
    });

    // Stream in changes file
    fs.readFile('./'   changesFile, 'utf-8', (err, jsonString) => {
    if (err)  {
            console.log(err);
        } else {
            try {
                const data = JSON.parse(jsonString);
            
                const array = [];

                Object.entries(data).map(([key, [{ action,  payload }]]) => {
                    switch (key) {
                        case 'users': {
                            if (action === 'add') {
                                console.log("it's an add");
                                array.push([`${key}`, `${payload}`]);
                            }
                        break;
                        }

                     case 'playlists': {
                        if (action === 'add') {
                            console.log("it's an add");
                            array.push([`${key}`, `${payload}`]);
                        }
                            break;
                        }
                    
                        case 'songs': {
                        if (action === 'add') {
                            console.log("it's an add");
                            array.push([`${key}`, `${payload}`]);
                        }
                        break;
                    }
                 }
                });
                
                console.log(array);

            } catch (err) {
                console.log('Error parsing JSON', err);
            }
        }
    }); 

    // after we have merged changes and source we need to write out
    // Don't know how to merge the changes array I created above back into the 
    // source.json file?
    fs.appendFile('./'   outputFile, JSON.stringify(array, null, 2), err => {
        if (err) {
            console.log(err);
        } else {
            console.log('File sucessfully written');
        }
    });

CodePudding user response:

I'm not 100% sure where you're going with your implementation, but I think a better way to go about this would be to update the original data object with the changes, and then write the changes out to a file:

const data = JSON.parse(fs.readFileSync(inputFile));
const changes = JSON.parse(fs.readFileSync(changesFile));

for(const [table, actions] of Object.entries(changes)){
    if(!(table in data))continue;
    for(const actionDetail of actions){
        if(actionDetail.action === 'add'){
            data[table].push(...actionDetail.payload);
        }
    }
}
fs.writeFileSync(inputFile, JSON.stringify(data));
  • Related