I have a source.json
that contains playlist entries like so:
"playlists" : [
{
"id" : "1",
"owner_id" : "2",
"song_ids" : [
"8",
"32"
]
},
{
"id" : "2",
"owner_id" : "3",
"song_ids" : [
"6",
"8",
"11"
]
},
{
"id" : "3",
"owner_id" : "7",
"song_ids" : [
"7",
"12",
"13",
"16",
"2"
]
}
]
and then a changes.json
file that has updates I want to make to the source.json
file:
{
"playlists": [{
"action": "update",
"payload": [{
"id": "1",
"owner_id": "2",
"song_ids": [
"1"
]
}]
},
{
"action": "create",
"payload": [{
"id": "1",
"owner_id": "2",
"song_ids": [
"8",
"32"
]
}]
},
{
"action": "delete",
"payload": [{
"id": "1"
}]
}
]
}
It's a command line program, that in the json contains directives on how to process, i.e. "action":"update"
and then the payload
to update with. After mutating the array, I wish to write out the updated result to output.json
. I have the code working pretty good, but there is one problem. When it updates it leaves the old entries in the original array. How do you remove those original entries before updating?
Here is my code:
// Stream in source file
const data = JSON.parse(fs.readFileSync('./' inputFile));
// Stream in changes file
const changes = JSON.parse(fs.readFileSync('./' changesFile));
for(const [table, actions] of Object.entries(changes)) {
if(!(table in data))continue;
// iterate through inner CRUD directives and mutate payloads
for(const actionDetail of actions) {
if(actionDetail.action === 'create') {
console.log('This is a CREATE entry');
data[table].push(...actionDetail.payload);
}
if(actionDetail.action === 'delete') {
console.log('This is a DELETE entry');
}
if(actionDetail.action === 'update') {
console.log('This is a UPDATE entry');
// const playlistUpdate = get id's from changes.json to update;
const result = data.playlists.filter(playlist => playlist.id !== playlistUpdate);
// grr! writes mutation but leaves old entries in original source.json playlist array of objects. grr.
data[table].push(result);
}
}
}
fs.writeFileSync('output.json', JSON.stringify(data, null, 2));
The current output.json
It doesn't update the id: 1
with new payload, it concatenates. grr.
"playlists": [
{
"id": "1",
"owner_id": "2",
"song_ids": [
"8",
"32"
]
},
{
"id": "2",
"owner_id": "3",
"song_ids": [
"6",
"8",
"11"
]
},
{
"id": "3",
"owner_id": "7",
"song_ids": [
"7",
"12",
"13",
"16",
"2"
]
},
{
"id": "1",
"owner_id": "2",
"song_ids": [
"1"
]
}
]
CodePudding user response:
do you mean that after you filter you still have old entries?
CodePudding user response:
You could do something like this:
...
if(actionDetail.action === 'update') {
// const playlistUpdate = get id's from changes.json to update;
const playlists = data.playlists.map(function updateCallback(playlist) {
if(playlistUpdate.indexOf(playlist.id) === -1) {
return playlist; // if not required to update, return original
}
// Modify the playlist based on the update & return the same.
return modifiedVersion;
});
data[table] = playlists;
}
...