0

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

JSON C11
  • 11,272
  • 7
  • 78
  • 65
Paulo C
  • 23
  • 1
  • 9

2 Answers2

2

There is two problems:

  1. You use push what is insert a new item into your list, this is the reason of the 'duplication'

  2. 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;
Gergo
  • 2,190
  • 22
  • 24
  • Having said that, it sure looks like what he's doing would be easier if his data structure was based on the item ids rather than the index. – Paul Feb 06 '16 at 23:03
  • Thanks for your answer Festo But how to add the updated item to the array without push?? – Paulo C Feb 06 '16 at 23:49
  • update the index config[index] = item index should be the index of the element. you can scan for it with for loop, or save it before when you get it. – Alon Feb 07 '16 at 00:05
  • I try to loop like this [link](http://stackoverflow.com/a/31965780/5888714) but didn't work.Maybe i will start searching to implement external database like mongodb – Paulo C Feb 07 '16 at 01:45
  • Thanks Festo i started using lodash but now my id disappeared.On the update function i use lodash like this: `var index = _.indexOf(config, _.find(config, item));` `config.splice(index, 1, item);` and then `json.stringify(config,null,4)` on posts.json the id of the updated item is gone.?? – Paulo C Feb 07 '16 at 16:09
0

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>
Bogdan Gishka
  • 254
  • 1
  • 12