Reputation: 23
I'm trying to update items stored in a JSON file in a Express App. Basically I'm reading the contents of the JSON file updating the item fetched by Id and writing to the file the updated item.Problem? It's appending the updated item so I get a duplicated. I can't see where is the error?
posts.json:
[
{
"name": "first name",
"description": "test first description",
"slug": "first-name",
"id": "2f065d59"
},
{
"name": "second name",
"description": "test second description",
"slug": "second-name",
"id": "0071b034"
}
]
create-update-delete.js:
var express = require('express');
var Creatordb = require('./database/posts.json');
var fs = require('fs');
var uuid = require('node-uuid');
var _ = require('lodash');
//Create The Item
var add = function (item) {
var id = uuid.v4();
item.id = id;
Creatordb[item.id] = item;
var outputFilename = './database/posts.json';
function appendObject(obj){
var configFile = fs.readFileSync(outputFilename);
var config = JSON.parse(configFile);
config.push(obj);
var configJSON = JSON.stringify(config, null, 4);
fs.writeFileSync(outputFilename, configJSON);
}
appendObject(item);
};
//Get The Item by Id
var getById = function (id) {
for(var i=0;i<Creatordb.length;i++) {
var id = Creatordb[i].id;
}
return id;
};
//Update The Item
var update = function (item) {
var outputFilename = './database/posts.json';
var configFile = fs.readFileSync(outputFilename);
var config = JSON.parse(configFile);
//using lodash??
var index = _.indexOf(config, _.find(config, item));
config.splice(index, 1, item);
var configJSON = JSON.stringify(config, null, 4);
fs.writeFileSync(outputFilename, configJSON);
};
If I update an item the posts.json will look like this:
[
{
"name": "first name",
"description": "test first description",
"slug": "first-name",
"id": "2f065d59"
},
{
"name": "second name edited",
"description": "test second description edited",
"slug": "second-name-edited",
//this id disappeared "id": "0071b034"//
}
]
Now with lodash the Id in the updated item is gone away? Can anyone explain? - Thanks
Upvotes: 0
Views: 2259
Reputation: 484
I don't understand, why do you use splice
function in the update
? In JavaScript, when you deal with objects or arrays, you work with their references, not copies. So, you can replace splice
with this one:
var obj = _.find(config, ['id', item.id]);
_.assign(obj, item);
In this case, you don't care, if item has all necessary fields, since assign
method will update only those fields, that were specified.
At the same time, if you 100% sure that new item will always have all fields specified, then Festo's solution is better, since it just replaces a reference of the old item on the new one, which is much faster.
var config = [
{
"name": "first name",
"description": "test first description",
"slug": "first-name",
"id": "2f065d59"
},
{
"name": "second name",
"description": "test second description",
"slug": "second-name",
"id": "0071b034"
}
];
function update(item) {
// Your read file logic.
var obj = _.find(config, ['id', item.id]);
_.assign(obj, item);
// Your write file logic.
}
console.log('config befor update:', config);
update({
"name": "third name",
"id": "0071b034"
});
console.log('config after update:', config);
<script src="https://cdn.jsdelivr.net/lodash/4.17.2/lodash.min.js"></script>
Upvotes: 0
Reputation: 2290
There is two problems:
You use push
what is insert a new item into your list, this is the reason of the 'duplication'
config[item.id] = item;
is not a valid reference. Your config is not like this:
["0071b034": { name: "Foo"}]
So the keys in config are 0,1,2 and not the item.id
I suggest to use lodash. There are a lots of useful functions, but if you stick this implementation, use this:
function findIndex(collection, id) {
for(var i=0; i<collection.length; i++) {
if (collection[i].id === id) {
return i;
}
}
}
// In your update function
var index = findIndex(config, item.id);
config[index] = item;
Upvotes: 2