125

How do I update a value in a json file and save it through node.js? I have the file content:

var file_content = fs.readFileSync(filename);
var content = JSON.parse(file_content);
var val1 = content.val1;

Now I want to change the value of val1 and save it to the file.

jsbeckr
  • 1,183
  • 1
  • 10
  • 24
Nava Polak Onik
  • 1,509
  • 2
  • 13
  • 17

8 Answers8

196

Doing this asynchronously is quite easy. It's particularly useful if you're concerned with blocking the thread (likely). Otherwise, I'd suggest Peter Lyon's answer

const fs = require('fs');
const fileName = './file.json';
const file = require(fileName);
    
file.key = "new value";
    
fs.writeFile(fileName, JSON.stringify(file), function writeJSON(err) {
  if (err) return console.log(err);
  console.log(JSON.stringify(file));
  console.log('writing to ' + fileName);
});

The caveat is that json is written to the file on one line and not prettified. ex:

{
  "key": "value"
}

will be...

{"key": "value"}

To avoid this, simply add these two extra arguments to JSON.stringify

JSON.stringify(file, null, 2)

null - represents the replacer function. (in this case we don't want to alter the process)

2 - represents the spaces to indent.

Seth
  • 10,198
  • 10
  • 45
  • 68
60
//change the value in the in-memory object
content.val1 = 42;
//Serialize as JSON and Write it to a file
fs.writeFileSync(filename, JSON.stringify(content));
Peter Lyons
  • 142,938
  • 30
  • 279
  • 274
  • 7
    Overall, it would be better to use an async write as this is the main focus of Node. Of course, without seeing the surrounding code it would be hard to give a definitive answer. It is unlikely that you would really need a sync unless you are need to be absolutely sure nothing else can happen until the write has completed. Additionally, of course, this should have an error checker since you can NEVER be sure that a file write will succeed. – Julian Knight May 22 '12 at 10:50
  • 8
    async vs. sync depends exactly on what you are doing in what context. If this is in a network service, you need async. For a command line utility, sync is the appropriate paradigm in most simple cases, but just knee-jerk saying "async is better" is not correct. My snippet is based on the OP snippet for context. The question is also not about error handling and if the file write fails, exiting with a stack trace is reasonable default behavior because there's not much you can do to recover from that. – Peter Lyons Apr 11 '15 at 02:30
  • Because node is loop based, async is nearly always better so you don't block the loop, this isn't a knee-jerk reaction at all, simply standard practice for node Dev. I already said that it depends on the requirement and I don't think the Q says anything about command line? Also in general, if this is part of a larger set of code (not clarified by the OP), then error handling is always smart and best practice. Dumping a stack trace is ok for Devs but crap for everyone else. – Julian Knight Apr 11 '15 at 11:19
  • 30
    async is a concurrency technique. If you need concurrency, async is required for node to work properly (not "better"). If you don't have concurrency, you don't need async. The point is you need to actually understand what async does for you and why. It's not inherently "better" for no reason and you don't need to memorize it as a "best practice". If the OP is writing a command line utility to alter a JSON file then exit, async complicates the code for no reason as the concurrency is not required. – Peter Lyons Apr 11 '15 at 14:02
  • 1
    I am building a node command line tool. If it is not sync written, the file could be locked when the output of my tool gets chained to the next tool. There are very good reasons to use sync. And good reasons to use async. – TamusJRoyce Oct 31 '18 at 19:05
11
// read file and make object
let content = JSON.parse(fs.readFileSync('file.json', 'utf8'));
// edit or add property
content.expiry_date = 999999999999;
//write file
fs.writeFileSync('file.json', JSON.stringify(content));
Apoorva Shah
  • 632
  • 1
  • 6
  • 15
5

addition to the previous answer add file path directory for the write operation

 fs.writeFile(path.join(__dirname,jsonPath), JSON.stringify(newFileData), function (err) {})
Luke Schoen
  • 4,129
  • 2
  • 27
  • 25
satej sarker
  • 310
  • 3
  • 6
3

I would strongly recommend not to use synchronous (blocking) functions, as they hold other concurrent operations. Instead, use asynchronous fs.promises:

const fs = require('fs').promises

const setValue = (fn, value) => 
  fs.readFile(fn)
    .then(body => JSON.parse(body))
    .then(json => {
      // manipulate your data here
      json.value = value
      return json
    })
    .then(json => JSON.stringify(json))
    .then(body => fs.writeFile(fn, body))
    .catch(error => console.warn(error))

Remeber that setValue returns a pending promise, you'll need to use .then function or, within async functions, the await operator.

// await operator
await setValue('temp.json', 1)           // save "value": 1
await setValue('temp.json', 2)           // then "value": 2
await setValue('temp.json', 3)           // then "value": 3

// then-sequence
setValue('temp.json', 1)                 // save "value": 1
  .then(() => setValue('temp.json', 2))  // then save "value": 2
  .then(() => setValue('temp.json', 3))  // then save "value": 3
ΔO 'delta zero'
  • 3,506
  • 1
  • 19
  • 31
2

For those looking to add an item to a json collection

function save(item, path = './collection.json'){
    if (!fs.existsSync(path)) {
        fs.writeFile(path, JSON.stringify([item]));
    } else {
        var data = fs.readFileSync(path, 'utf8');  
        var list = (data.length) ? JSON.parse(data): [];
        if (list instanceof Array) list.push(item)
        else list = [item]  
        fs.writeFileSync(path, JSON.stringify(list));
    }
}
Spankied
  • 1,626
  • 13
  • 21
2

Save data after task completion

fs.readFile("./sample.json", 'utf8', function readFileCallback(err, data) {
        if (err) {
          console.log(err);
        } else {
          fs.writeFile("./sample.json", JSON.stringify(result), 'utf8', err => {
            if (err) throw err;
            console.log('File has been saved!');
          });
        }
      });
Gaurav Mogha
  • 370
  • 3
  • 9
0

Promise based solution [Javascript (ES6) + Node.js (V10 or above)]

const fsPromises = require('fs').promises;
fsPromises.readFile('myFile.json', 'utf8') 
        .then(data => { 
                let json = JSON.parse(data);
                //// Here - update your json as per your requirement ////

                fsPromises.writeFile('myFile.json', JSON.stringify(json))
                        .then(  () => { console.log('Update Success'); })
                        .catch(err => { console.log("Update Failed: " + err);});
            })
        .catch(err => { console.log("Read Error: " +err);});

If your project supports Javascript ES8 then you could use asyn/await instead of native promise.

SridharKritha
  • 8,481
  • 2
  • 52
  • 43