2016-02-06 2 views
0

Я пытаюсь обновить элементы, хранящиеся в файле JSON, в Express App. В основном я читаю содержимое файла JSON, обновляющего элемент, полученный с помощью идентификатора, и записывая в файл обновленный элемент. Проблема? Это добавление обновленного элемента, поэтому я получаю дубликат. Я не вижу, где ошибка?Найти и заменить элементы в файле Json

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" 
    } 
] 

создания-обновления-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); 

}; 

Если я обновить предмета у posts.json будет выглядеть это:

[ 
     { 
      "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"// 
     } 
    ] 

Теперь с lodash Идентификатор в обновленном элементе ушел? Может ли кто-нибудь объяснить? - Спасибо

ответ

2

Существует две проблемы:

  1. используется push что вставить новый элемент в списке, это причина «дублирования»

  2. config[item.id] = item; не является действительным Справка. Ваш конфиг не нравится:

    [ "0071b034": {имя: "Foo"}]

Так ключи в конфигурации являются 0,1,2 и не item.id

Я предлагаю использовать lodash. Есть еще много полезных функций, но если вы будете придерживаться этой реализации, используйте:

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; 
+0

Сказав это, он уверен, выглядит как то, что он делает бы легче, если его структура данных была основана на пункт идентификаторами, а не индекс. – Paul

+0

Спасибо за ваш ответ Festo Но как добавить обновленный элемент в массив без нажатия? –

+0

обновление индекса config [index] = item индекс должен быть индексом элемента.вы можете сканировать для него с помощью цикла for или сохранить его до того, когда вы его получите. – Alon

0

Я не понимаю, почему вы используете splice функцию в update? В JavaScript, когда вы имеете дело с объектами или массивами, вы работаете со своими ссылками, а не с копиями. Таким образом, вы можете заменить splice с этим:

var obj = _.find(config, ['id', item.id]); 
_.assign(obj, item); 

В этом случае, вам не все равно, если деталь имеет все необходимые поля, так как assign метод будет обновлять только те поля, которые были заданы.

В то же время, если вы на 100% уверены, что новый элемент всегда будет иметь все указанные поля, то решение Festo лучше, так как оно просто заменяет ссылку старого элемента на новом, что намного быстрее.

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>

Смежные вопросы